Beispiel #1
0
/* Timer pops every 1 ms, writing a new value to key.
 * After 10 calls, it calls kvs_unwatch().
 * After 20 calls, it calls flux_reactor_stop().
 * The kvs_unwatch_cb() counts the number of times it is called, should be 10.
 */
void test_unwatch (int argc, char **argv)
{
    struct timer_ctx ctx;
    flux_reactor_t *r;
    int count = 0;
    flux_watcher_t *timer;

    if (argc != 1) {
        fprintf (stderr, "Usage: unwatch key\n");
        exit (1);
    }
    ctx.key = argv[0];
    if (!(ctx.h = flux_open (NULL, 0)))
        log_err_exit ("flux_open");
    r = flux_get_reactor (ctx.h);
    if (kvs_watch_int (ctx.h, ctx.key, unwatch_watch_cb, &count) < 0)
        log_err_exit ("kvs_watch_int %s", ctx.key);
    if (!(timer = flux_timer_watcher_create (r, 0.001, 0.001,
                                             unwatch_timer_cb, &ctx)))
        log_err_exit ("flux_timer_watcher_create");
    flux_watcher_start (timer);
    if (flux_reactor_run (r, 0) < 0)
        log_err_exit ("flux_reactor_run");
    if (count != 10)
        log_msg_exit ("watch called %d times (should be 10)", count);
    flux_watcher_destroy (timer);
    flux_close (ctx.h);
}
Beispiel #2
0
struct alloc_ctx *alloc_ctx_create (flux_t *h, struct queue *queue,
                                    struct event_ctx *event_ctx)
{
    struct alloc_ctx *ctx;
    flux_reactor_t *r = flux_get_reactor (h);

    if (!(ctx = calloc (1, sizeof (*ctx))))
        return NULL;
    ctx->h = h;
    ctx->queue = queue;
    ctx->event_ctx = event_ctx;
    if (!(ctx->inqueue = queue_create (false)))
        goto error;
    if (flux_msg_handler_addvec (h, htab, ctx, &ctx->handlers) < 0)
        goto error;
    ctx->prep = flux_prepare_watcher_create (r, prep_cb, ctx);
    ctx->check = flux_check_watcher_create (r, check_cb, ctx);
    ctx->idle = flux_idle_watcher_create (r, NULL, NULL);
    if (!ctx->prep || !ctx->check || !ctx->idle) {
        errno = ENOMEM;
        goto error;
    }
    flux_watcher_start (ctx->prep);
    flux_watcher_start (ctx->check);
    event_ctx_set_alloc_ctx (event_ctx, ctx);
    return ctx;
error:
    alloc_ctx_destroy (ctx);
    return NULL;
}
Beispiel #3
0
void test_selfmod (int argc, char **argv)
{
    flux_t *h;
    char *key;

    if (argc != 1) {
        fprintf (stderr, "Usage: selfmod key\n");
        exit (1);
    }
    key = argv[0];
    if (!(h = flux_open (NULL, 0)))
        log_err_exit ("flux_open");

    if (kvs_put_int (h, key, -1) < 0)
        log_err_exit ("kvs_put_int");
    if (kvs_commit (h) < 0)
        log_err_exit ("kvs_commit");
    if (kvs_watch_int (h, key, selfmod_watch_cb, h) < 0)
        log_err_exit ("kvs_watch_int");

    log_msg ("reactor: start");
    flux_reactor_run (flux_get_reactor (h), 0);
    log_msg ("reactor: end");

    flux_close (h);
}
Beispiel #4
0
/* check:
 * Runs right after reactor calls poll(2).
 * Stop idle watcher, and send next alloc request, if available.
 */
static void check_cb (flux_reactor_t *r, flux_watcher_t *w,
                      int revents, void *arg)
{
    struct alloc_ctx *ctx = arg;
    struct job *job;

    flux_watcher_stop (ctx->idle);
    if (!ctx->ready)
        return;
    if (ctx->mode == SCHED_SINGLE && ctx->active_alloc_count > 0)
        return;
    if ((job = queue_first (ctx->inqueue))) {
        if (alloc_request (ctx, job) < 0) {
            flux_log_error (ctx->h, "alloc_request fatal error");
            flux_reactor_stop_error (flux_get_reactor (ctx->h));
            return;
        }
        queue_delete (ctx->inqueue, job, job->aux_queue_handle);
        job->aux_queue_handle = NULL;
        job->alloc_pending = 1;
        job->alloc_queued = 0;
        ctx->active_alloc_count++;
        if ((job->flags & FLUX_JOB_DEBUG))
            (void)event_job_post_pack (ctx->event_ctx, job,
                                       "debug.alloc-request", NULL);

    }
}
Beispiel #5
0
static void test_multmatch (flux_t h)
{
    flux_msg_handler_t *w1, *w2;
    struct flux_match m1 = FLUX_MATCH_ANY;
    struct flux_match m2 = FLUX_MATCH_ANY;

    m1.topic_glob = "foo.*";
    m2.topic_glob = "foo.bar";

    /* test #1: verify multiple match behaves as documented, that is,
     * a message is matched (only) by the most recently added watcher
     */
    ok ((w1 = flux_msg_handler_create (h, m1, multmatch1, NULL)) != NULL,
        "multmatch: first added handler for foo.*");
    ok ((w2 = flux_msg_handler_create (h, m2, multmatch2, NULL)) != NULL,
        "multmatch: next added handler for foo.bar");
    flux_msg_handler_start (w1);
    flux_msg_handler_start (w2);
    ok (send_request (h, "foo.bar") == 0,
        "multmatch: send foo.bar msg");
    ok (send_request (h, "foo.baz") == 0,
        "multmatch: send foo.baz msg");
    ok (flux_reactor_run (flux_get_reactor (h), 0) == 0 && multmatch_count == 2,
        "multmatch: last added watcher handled foo.bar");
    flux_msg_handler_destroy (w1);
    flux_msg_handler_destroy (w2);
}
Beispiel #6
0
int mod_main (flux_t *h, int argc, char **argv)
{
    ctx_t *ctx = getctx (h);
    uint32_t rank;
    flux_msg_handler_t **handlers = NULL;
    int rc = -1;

    if (flux_get_rank (h, &rank) < 0)
        return -1;
    if (rank != 0) {
        flux_log (h, LOG_ERR, "this module must only run on rank 0");
        return -1;
    }
    flux_log (h, LOG_INFO, "module starting");

    if (flux_event_subscribe (h, "sim.start") < 0) {
        flux_log (h, LOG_ERR, "subscribing to event: %s", strerror (errno));
        return -1;
    }
    if (flux_msg_handler_addvec (h, htab, ctx, &handlers) < 0) {
        flux_log (h, LOG_ERR, "flux_msg_handler_add: %s", strerror (errno));
        return -1;
    }

    send_alive_request (h, module_name);

    if (flux_reactor_run (flux_get_reactor (h), 0) < 0) {
        flux_log (h, LOG_ERR, "flux_reactor_run: %s", strerror (errno));
        goto done_delvec;
    }
    rc = 0;
done_delvec:
    flux_msg_handler_delvec (handlers);
    return rc;
}
int mod_main (flux_t *h, int argc, char **argv)
{
    flux_msg_handler_t **handlers = NULL;
    sqlite_ctx_t *ctx = getctx (h);
    if (!ctx)
        goto done;
    if (flux_event_subscribe (h, "shutdown") < 0) {
        flux_log_error (h, "flux_event_subscribe");
        goto done;
    }
    if (flux_msg_handler_addvec (h, htab, ctx, &handlers) < 0) {
        flux_log_error (h, "flux_msg_handler_addvec");
        goto done;
    }
    if (register_backing_store (h, true, "content-sqlite") < 0) {
        flux_log_error (h, "registering backing store");
        goto done;
    }
    if (register_content_backing_service (h) < 0) {
        flux_log_error (h, "service.add: content-backing");
        goto done;
    }
    if (flux_reactor_run (flux_get_reactor (h), 0) < 0) {
        flux_log_error (h, "flux_reactor_run");
        goto done;
    }
done:
    flux_msg_handler_delvec (handlers);
    return 0;
}
Beispiel #8
0
int mod_main (flux_t *h, int argc, char **argv)
{
    int saved_errno;
    flux_msg_handler_t **handlers = NULL;

    if (argc == 1 && !strcmp (argv[0], "--init-failure")) {
        flux_log (h, LOG_INFO, "aborting during init per test request");
        errno = EIO;
        goto error;
    }
    if (!(modules = zhash_new ())) {
        errno = ENOMEM;
        goto error;
    }
    if (flux_get_rank (h, &rank) < 0)
        goto error;
    if (flux_msg_handler_addvec (h, htab, NULL, &handlers) < 0)
        goto error;
    if (flux_reactor_run (flux_get_reactor (h), 0) < 0) {
        flux_log_error (h, "flux_reactor_run");
        goto error;
    }
    zhash_destroy (&modules);
    return 0;
error:
    saved_errno = errno;
    flux_msg_handler_delvec (handlers);
    zhash_destroy (&modules);
    errno = saved_errno;
    return -1;
}
Beispiel #9
0
int heartbeat_start (heartbeat_t *hb)
{
    uint32_t rank;
    struct flux_match match = FLUX_MATCH_EVENT;

    if (!hb->h) {
        errno = EINVAL;
        return -1;
    }
    if (flux_get_rank (hb->h, &rank) < 0)
        return -1;
    if (rank == 0) {
        flux_reactor_t *r = flux_get_reactor (hb->h);
        flux_reactor_now_update (r);
        if (!(hb->timer = flux_timer_watcher_create (r, hb->rate, hb->rate,
                                                     timer_cb, hb)))
            return -1;
        flux_watcher_start (hb->timer);
    }
    match.topic_glob = "hb";
    if (!(hb->mh = flux_msg_handler_create (hb->h, match, event_cb, hb)))
        return -1;
    flux_msg_handler_start (hb->mh);
    return 0;
}
Beispiel #10
0
int main (int argc, char **argv)
{
    flux_t h;
    heartbeat_t *hb;
    flux_msg_handler_t *w;

    plan (18);

    check_codec ();

    (void)setenv ("FLUX_CONNECTOR_PATH", CONNECTOR_PATH, 0);
    ok ((h = flux_open ("loop://", 0)) != NULL,
        "opened loop connector");
    if (!h)
        BAIL_OUT ("can't continue without loop handle");
    flux_fatal_set (h, fatal_err, NULL);

    ok ((hb = heartbeat_create ()) != NULL,
        "heartbeat_create works");

    heartbeat_set_flux (hb, h);

    ok (heartbeat_get_rate (hb) == 2.,
        "heartbeat_get_rate returns default of 2s");
    errno = 0;
    ok (heartbeat_set_rate (hb, -1) < 1 && errno == EINVAL,
        "heartbeat_set_rate -1 fails with EINVAL");
    errno = 0;
    ok (heartbeat_set_rate (hb, 1000000) < 1 && errno == EINVAL,
        "heartbeat_set_rate 1000000 fails with EINVAL");
    ok (heartbeat_set_ratestr (hb, "250ms") == 0,
        "heartbeat_set_ratestr 250ms works");
    ok (heartbeat_get_rate (hb) == 0.250,
        "heartbeat_get_rate returns what was set");
    ok (heartbeat_set_rate (hb, 0.1) == 0,
        "heartbeat_set_rate 0.1 works");
    ok (heartbeat_get_rate (hb) == 0.1,
        "heartbeat_get_rate returns what was set");

    ok (heartbeat_get_epoch (hb) == 0,
        "heartbeat_get_epoch works, default is zero");

    w = flux_msg_handler_create (h, FLUX_MATCH_EVENT, heartbeat_event_cb, hb);
    ok (w != NULL,
        "created event watcher");
    flux_msg_handler_start (w);

    ok (heartbeat_start (hb) == 0,
        "heartbeat_start works");

    ok (flux_reactor_run (flux_get_reactor (h), 0) == 0,
        "flux reactor exited normally");

    heartbeat_destroy (hb);
    flux_msg_handler_destroy (w);
    flux_close (h);

    done_testing ();
    return 0;
}
Beispiel #11
0
static struct dispatch *dispatch_get (flux_t h)
{
    struct dispatch *d = flux_aux_get (h, "flux::dispatch");
    if (!d) {
        flux_reactor_t *r = flux_get_reactor (h);
        if (!(d = malloc (sizeof (*d))))
            goto nomem;
        memset (d, 0, sizeof (*d));
        d->usecount = 1;
        if (!(d->handlers = zlist_new ()))
            goto nomem;
        if (!(d->handlers_new = zlist_new ()))
            goto nomem;
        d->h = h;
        d->w = flux_handle_watcher_create (r, h, FLUX_POLLIN, handle_cb, d);
        if (!d->w)
            goto nomem;
        fastpath_init (&d->norm);
        fastpath_init (&d->group);

        flux_aux_set (h, "flux::dispatch", d, dispatch_destroy);
    }
    return d;
nomem:
    dispatch_destroy (d);
    errno = ENOMEM;
    return NULL;
}
Beispiel #12
0
int mod_main (flux_t *h, int argc, char **argv)
{
    int rc = -1;
    ctx_t *ctx = getctx (h);

    if (!ctx)
        goto done;
    if (flux_event_subscribe (h, "barrier.") < 0) {
        flux_log_error (h, "flux_event_subscribe");
        goto done;
    }
    if (flux_msg_handler_addvec (h, htab, ctx) < 0) {
        flux_log_error (h, "flux_msghandler_add");
        goto done;
    }
    if (flux_reactor_run (flux_get_reactor (h), 0) < 0) {
        flux_log_error (h, "flux_reactor_run");
        goto done_unreg;
    }
    rc = 0;
done_unreg:
    flux_msg_handler_delvec (htab);
done:
    return rc;
}
Beispiel #13
0
static int wait_job_complete (flux_t h)
{
    int rc = -1;
    sig_flux_h = h;
    wjctx_t *ctx = getctx (h);

    if (signal (SIGINT, sig_handler) == SIG_ERR)
        goto done;

    if (jsc_notify_status (h, waitjob_cb, (void *)h) != 0) {
        flux_log (h, LOG_ERR, "failed to register a waitjob CB");
    }
    /* once jsc_notify_status is returned, all of JSC events
     * will be queued and delivered. It is safe to signal
     * readiness.
     */
    if (ctx->start)
        touch_outfile (ctx->start);

    if (complete_job (ctx)) {
        if (ctx->complete)
            touch_outfile (ctx->complete);
        flux_log (ctx->h, LOG_INFO, "wait_job_complete: completion detected");
    }
    if (flux_reactor_run (flux_get_reactor (h), 0) < 0) {
        flux_log (h, LOG_ERR, "error in flux_reactor_run");
        goto done;
    }
    rc = 0;
done:
    return rc;
}
Beispiel #14
0
void *thread (void *arg)
{
    thd_t *t = arg;

    if (!(t->h = flux_open (NULL, 0))) {
        log_err ("%d: flux_open", t->n);
        goto done;
    }
    signal_ready ();
    /* The first kvs.watch reply is handled synchronously, then other kvs.watch
     * replies will arrive asynchronously and be handled by the reactor.
     */
    if (kvs_watch_int (t->h, key, mt_watch_cb, t) < 0) {
        log_err ("%d: kvs_watch_int", t->n);
        goto done;
    }
    if (kvs_watch_int (t->h, "nonexistent-key", mt_watchnil_cb, t) < 0) {
        log_err ("%d: kvs_watch_int", t->n);
        goto done;
    }
    if (kvs_watch_int (t->h, key_stable, mt_watchstable_cb, t) < 0) {
        log_err ("%d: kvs_watch_int", t->n);
        goto done;
    }
    if (flux_reactor_run (flux_get_reactor (t->h), 0) < 0) {
        log_err ("%d: flux_reactor_run", t->n);
        goto done;
    }
done:
    if (t->h)
        flux_close (t->h);

    return NULL;
}
Beispiel #15
0
int main (int argc, char *argv[])
{
    flux_t h;
    flux_reactor_t *reactor;

    plan (4+11+3+4+3+5+2);

    (void)setenv ("FLUX_CONNECTOR_PATH", CONNECTOR_PATH, 0);
    ok ((h = flux_open ("loop://", 0)) != NULL,
        "opened loop connector");
    if (!h)
        BAIL_OUT ("can't continue without loop handle");
    flux_fatal_set (h, fatal_err, NULL);
    ok ((reactor = flux_get_reactor (h)) != NULL,
        "obtained reactor");
    if (!reactor)
        BAIL_OUT ("can't continue without reactor");

    ok (flux_reactor_run (reactor, 0) == 0,
        "general: reactor ran to completion (no watchers)");
    errno = 0;
    ok (flux_sleep_on (h, FLUX_MATCH_ANY) < 0 && errno == EINVAL,
        "general: flux_sleep_on outside coproc fails with EINVAL");

    test_timer (reactor); // 11
    test_fd (reactor); // 3
    test_zmq (reactor); // 4
    test_msg (h); // 3
    test_multmatch (h); // 5

    /* Misc
     */
    lives_ok ({ reactor_destroy_early ();},
        "destroying reactor then watcher doesn't segfault");
Beispiel #16
0
static ctx_t *getctx (flux_t *h)
{
    ctx_t *ctx = (ctx_t *)flux_aux_get (h, "flux::barrier");

    if (!ctx) {
        ctx = xzmalloc (sizeof (*ctx));
        if (!(ctx->barriers = zhash_new ())) {
            errno = ENOMEM;
            goto error;
        }
        if (flux_get_rank (h, &ctx->rank) < 0) {
            flux_log_error (h, "flux_get_rank");
            goto error;
        }
        if (!(ctx->timer = flux_timer_watcher_create (flux_get_reactor (h),
                       barrier_reduction_timeout_sec, 0., timeout_cb, ctx) )) {
            flux_log_error (h, "flux_timer_watacher_create");
            goto error;
        }
        ctx->h = h;
        flux_aux_set (h, "flux::barrier", ctx, freectx);
    }
    return ctx;
error:
    freectx (ctx);
    return NULL;
}
Beispiel #17
0
int mod_main (flux_t h, int argc, char **argv)
{
    int saved_errno;
    ctx_t *ctx = getctx (h);

    if (!ctx) {
        saved_errno = errno;
        flux_log_error (h, "error allocating context");
        goto error;
    }
    if (flux_msg_handler_addvec (h, htab, ctx) < 0) {
        saved_errno = errno;
        flux_log_error (h, "flux_msg_handler_addvec");
        goto error;
    }
    if (flux_reactor_run (flux_get_reactor (h), 0) < 0) {
        saved_errno = errno;
        flux_log_error (h, "flux_reactor_run");
        flux_msg_handler_delvec (htab);
        goto error;
    }
    flux_msg_handler_delvec (htab);
    return 0;
error:
    errno = saved_errno;
    return -1;
}
Beispiel #18
0
/* Handle the simplest possible request.
 * Verify that everything is as expected; log it and stop the reactor if not.
 */
void null_request_cb (flux_t h, flux_msg_handler_t *w,
                      const flux_msg_t *msg, void *arg)
{
    ctx_t *ctx = arg;
    const char *topic;
    int type, size;
    void *buf;
    uint32_t nodeid;
    int flags;

    if (!msg) {
        flux_log (h, LOG_ERR, "%s: got NULL msg!", __FUNCTION__);
        goto error;
    }
    if (flux_msg_get_type (msg, &type) < 0) {
        flux_log_error (h, "%s: flux_msg_get_type", __FUNCTION__);
        goto error;
    }
    if (type != FLUX_MSGTYPE_REQUEST) {
        flux_log (h, LOG_ERR, "%s: unexpected type %s", __FUNCTION__,
                  flux_msg_typestr (type));
        goto error;
    }
    if (flux_msg_get_nodeid (msg, &nodeid, &flags) < 0) {
        flux_log_error (h, "%s: flux_msg_get_nodeid", __FUNCTION__);
        goto error;
    }
    if (nodeid != ctx->rank && nodeid != FLUX_NODEID_ANY) {
        flux_log (h, LOG_ERR, "%s: unexpected nodeid: %"PRIu32"", __FUNCTION__,
                  nodeid);
        goto error;
    }
    if (flux_msg_get_topic (msg, &topic) < 0) {
        flux_log_error (h, "%s: flux_msg_get_topic", __FUNCTION__);
        goto error;
    }
    if (strcmp (topic, "req.null") != 0) {
        flux_log (h, LOG_ERR, "%s: unexpected topic: %s", __FUNCTION__,
                  topic);
        goto error;
    }
    if (flux_msg_get_payload (msg, &flags, &buf, &size) == 0) {
        flux_log (h, LOG_ERR, "%s: unexpected payload size %d", __FUNCTION__,
                  size);
        goto error;
    }
    if (errno != EPROTO) {
        flux_log (h, LOG_ERR, "%s: get nonexistent payload: %s", __FUNCTION__,
                  strerror (errno));
        goto error;
    }
    if (flux_respond (h, msg, 0, NULL) < 0) {
        flux_log_error (h, "%s: flux_respond", __FUNCTION__);
        goto error;
    }
    return;
error:
    flux_reactor_stop_error (flux_get_reactor (h));
}
Beispiel #19
0
static void multmatch2 (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg,
                        void *arg)
{
    const char *topic;
    if (flux_msg_get_topic (msg, &topic) < 0 || strcmp (topic, "foo.bar"))
        flux_reactor_stop_error (flux_get_reactor (h));
    flux_msg_handler_stop (w);
    multmatch_count++;
}
Beispiel #20
0
static void then_cb (flux_rpc_t *r, void *arg)
{
    flux_t h = arg;
    uint32_t nodeid;

    if (flux_rpc_get (r, &nodeid, NULL) < 0
            || !nodeset_add_rank (then_ns, nodeid)
            || ++then_count == 128) {
        flux_reactor_stop (flux_get_reactor (h));
    }
}
Beispiel #21
0
void *watchthread (void *arg)
{
    thd_t *t = arg;
    watch_count_t wc;
    flux_kvs_txn_t *txn;
    flux_future_t *f;
    flux_reactor_t *r;
    flux_watcher_t *pw = NULL;
    flux_watcher_t *tw = NULL;

    if (!(t->h = flux_open (NULL, 0)))
        log_err_exit ("flux_open");

    /* Make sure key doesn't already exist, initial value may affect
     * test by chance (i.e. initial value = 0, commit 0 and thus no
     * change)
     */
    if (!(txn = flux_kvs_txn_create ()))
        log_err_exit ("flux_kvs_txn_create");
    if (flux_kvs_txn_unlink (txn, 0, key) < 0)
        log_err_exit ("flux_kvs_txn_unlink");
    if (!(f = flux_kvs_commit (t->h, 0, txn)) || flux_future_get (f, NULL) < 0)
        log_err_exit ("flux_kvs_commit");
    flux_future_destroy (f);
    flux_kvs_txn_destroy (txn);

    r = flux_get_reactor (t->h);

    if (flux_kvs_watch (t->h, key, watch_count_cb, t) < 0)
        log_err_exit ("flux_kvs_watch %s", key);

    pw = flux_prepare_watcher_create (r, watch_prepare_cb, NULL);

    wc.t = t;
    wc.lastcount = -1;

    /* So test won't hang if there's a bug */
    tw = flux_timer_watcher_create (r,
                                    WATCH_TIMEOUT,
                                    WATCH_TIMEOUT,
                                    watch_timeout_cb,
                                    &wc);

    flux_watcher_start (pw);
    flux_watcher_start (tw);

    if (flux_reactor_run (r, 0) < 0)
        log_err_exit ("flux_reactor_run");

    flux_watcher_destroy (pw);
    flux_watcher_destroy (tw);
    flux_close (t->h);
    return NULL;
}
Beispiel #22
0
static void then_cb (flux_rpc_t *r, void *arg)
{
    flux_t *h = arg;
    const char *json_str;

    ok (flux_rpc_check (r) == true,
        "flux_rpc_check says get won't block in then callback");
    json_str = NULL;
    ok (flux_rpc_get (r, &json_str) == 0
        && json_str && !strcmp (json_str, "{}"),
        "flux_rpc_get works and returned expected payload in then callback");
    flux_reactor_stop (flux_get_reactor (h));
}
Beispiel #23
0
int mod_main (flux_t *h, int argc, char **argv)
{
    zhash_t *args = zhash_fromargv (argc, argv);
    ctx_t *ctx;
    char *eoc_str;
    bool exit_on_complete;
    uint32_t rank;

    if (flux_get_rank (h, &rank) < 0)
        return -1;

    if (rank != 0) {
        flux_log (h, LOG_ERR, "sim module must only run on rank 0");
        return -1;
    }

    flux_log (h, LOG_INFO, "sim comms module starting");

    if (!(eoc_str = zhash_lookup (args, "exit-on-complete"))) {
        flux_log (h,
                  LOG_ERR,
                  "exit-on-complete argument is not set, defaulting to false");
        exit_on_complete = false;
    } else {
        exit_on_complete =
            (!strcmp (eoc_str, "true") || !strcmp (eoc_str, "True"));
    }
    ctx = getctx (h, exit_on_complete);

    if (flux_event_subscribe (h, "rdl.update") < 0) {
        flux_log (h, LOG_ERR, "subscribing to event: %s", strerror (errno));
        return -1;
    }

    if (flux_msg_handler_addvec (h, htab, ctx) < 0) {
        flux_log (h, LOG_ERR, "flux_msg_handler_add: %s", strerror (errno));
        return -1;
    }

    if (send_start_event (h) < 0) {
        flux_log (h, LOG_ERR, "sim failed to send start event");
        return -1;
    }
    flux_log (h, LOG_DEBUG, "sim sent start event");

    if (flux_reactor_run (flux_get_reactor (h), 0) < 0) {
        flux_log (h, LOG_ERR, "flux_reactor_run: %s", strerror (errno));
        return -1;
    }
    return 0;
}
Beispiel #24
0
int main (int argc, char *argv[])
{
    flux_msg_t *msg;
    flux_t h;
    flux_reactor_t *reactor;

    plan (35);

    (void)setenv ("FLUX_CONNECTOR_PATH", CONNECTOR_PATH, 0);
    ok ((h = flux_open ("loop://", FLUX_O_COPROC)) != NULL,
        "opened loop connector");
    if (!h)
        BAIL_OUT ("can't continue without loop handle");
    ok ((reactor = flux_get_reactor (h)) != NULL,
        "obtained reactor");
    if (!reactor)
        BAIL_OUT ("can't continue without reactor");

    flux_fatal_set (h, fatal_err, NULL);
    flux_fatal_error (h, __FUNCTION__, "Foo");
    ok (fatal_tested == true,
        "flux_fatal function is called on fatal error");

    /* create nodeset for last _then test */
    ok ((then_ns = nodeset_create ()) != NULL,
        "nodeset created ok");

    ok (flux_msghandler_addvec (h, htab, htablen, NULL) == 0,
        "registered message handlers");
    /* test continues in rpctest_begin_cb() so that rpc calls
     * can sleep while we answer them
     */
    ok ((msg = flux_request_encode ("rpctest.begin", NULL)) != NULL
        && flux_send (h, msg, 0) == 0,
        "sent message to initiate test");
    ok (flux_reactor_run (reactor, 0) == 0,
        "reactor completed normally");
    flux_msg_destroy (msg);

    /* Check result of last _then test */
    ok (nodeset_count (then_ns) == 128,
        "then callback worked with correct nodemap");
    nodeset_destroy (then_ns);
    flux_rpc_destroy (then_r);

    flux_close (h);

    done_testing();
    return (0);
}
Beispiel #25
0
static int runlevel_start_subprocess (runlevel_t *r, int level)
{
    flux_subprocess_t *p = NULL;

    assert (r->h != NULL);

    if (r->rc[level].cmd) {
        flux_subprocess_ops_t ops = {
            .on_completion = completion_cb,
            .on_state_change = NULL,
            .on_channel_out = NULL,
            .on_stdout = NULL,
            .on_stderr = NULL,
        };
        flux_reactor_t *reactor = flux_get_reactor (r->h);
        int flags = 0;

        /* set alternate io callback for levels 1 and 3 */
        if (level == 1 || level == 3) {
            ops.on_stdout = io_cb;
            ops.on_stderr = io_cb;
        }
        else
            flags |= FLUX_SUBPROCESS_FLAGS_STDIO_FALLTHROUGH;

        if (!(p = flux_exec (r->h,
                             flags,
                             r->rc[level].cmd,
                             &ops)))
            goto error;

        if (flux_subprocess_aux_set (p, "runlevel", r, NULL) < 0)
            goto error;

        monotime (&r->rc[level].start);
        if (r->rc[level].timeout > 0.) {
            flux_watcher_t *w;
            if (!(w = flux_timer_watcher_create (reactor,
                                                 r->rc[level].timeout, 0.,
                                                 runlevel_timeout, r)))
                goto error;
            flux_watcher_start (w);
            r->rc[level].timer = w;
            flux_log (r->h, LOG_INFO, "runlevel %d (%.1fs) timer started",
                      level, r->rc[level].timeout);
        }

        r->rc[level].p = p;
    } else {
Beispiel #26
0
static int unwatch_timer_cb (flux_t h, void *arg)
{
    static int count = 0;
    const char *key = arg;
    if (kvs_put_int (h, key, count++) < 0)
        err_exit ("%s: kvs_put_int", __FUNCTION__);
    if (kvs_commit (h) < 0)
        err_exit ("%s: kvs_commit", __FUNCTION__);
    if (count == 10) {
        if (kvs_unwatch (h, key) < 0)
            err_exit ("%s: kvs_unwatch", __FUNCTION__);
    } else if (count == 20)
        flux_reactor_stop (flux_get_reactor (h));
    return 0;
}
Beispiel #27
0
static void event_handler (flux_t *h, flux_msg_handler_t *w,
                           const flux_msg_t *msg, void *arg)
{
    cron_entry_t *e = arg;
    struct cron_event *ev = cron_entry_type_data (e);

    ev->counter++;
    if (ev->paused)
        return;
    /*
     *  Determine if we should run the cron task on this event
     *   based on the current values for "after" and "nth".
     *   If ev->after is set, then only run for the first time
     *   after we've seen this many events. If ev->nth is set,
     *   only run every nth event starting with 'after'.
     */
    if (ev->counter < ev->after)
        return;
    if (ev->nth && ((ev->counter - ev->after) % ev->nth))
        return;
    if (ev->min_interval > 0.) {
        double now = get_timestamp ();
        double remaining = ev->min_interval - (now - e->stats.lastrun);
        if (remaining > 1e-5) {
            flux_reactor_t *r = flux_get_reactor (h);
            flux_watcher_t *w;
            if (!(w = flux_timer_watcher_create (r, remaining, 0.,
                                                 ev_timer_cb, (void *) e)))
                flux_log_error (h, "timer_watcher_create");
            else {
                /* Pause the event watcher. Continue to count events but
                 *  don't run anything until we unpause.
                 */
                ev->paused = 1;
                flux_watcher_start (w);
                flux_log (h, LOG_DEBUG,
                          "cron-%ju: delaying %4.03fs due to min interval",
                          e->id, remaining);
            }
            return;
        }
    }
    cron_entry_schedule_task (e);
}
Beispiel #28
0
static struct dispatch *dispatch_get (flux_t h)
{
    struct dispatch *d = flux_aux_get (h, "flux::dispatch");
    if (!d) {
        flux_reactor_t *r = flux_get_reactor (h);
        d = xzmalloc (sizeof (*d));
        d->handlers = zlist_new ();
        d->waiters = zlist_new ();
        if (!d->handlers || !d->waiters)
            oom ();
        d->h = h;
        d->w = flux_handle_watcher_create (r, h, FLUX_POLLIN, handle_cb, d);
        if (!d->w)
            oom ();
        d->usecount = 1;
        flux_aux_set (h, "flux::dispatch", d, dispatch_destroy);
    }
    return d;
}
Beispiel #29
0
/* expect val: {-1,0,1,...,(changes - 1)}
 * count will therefore run 0...changes.
 */
static int mt_watch_cb (const char *k, int val, void *arg, int errnum)
{
    thd_t *t = arg;
    if (errnum != 0) {
        log_errn (errnum, "%d: %s", t->n, __FUNCTION__);
        return -1;
    }
    if (val == t->last_val) {
        log_msg ("%d: %s: called with same value as last time: %d", t->n,
            __FUNCTION__, val);
        return -1;
    }
    t->last_val = val;

    /* normal stop */
    if (val + 1 == changes)
        flux_reactor_stop (flux_get_reactor (t->h));
    t->change_count++;
    return 0;
}
Beispiel #30
0
static int handle_notify_req (flux_t h, const char *ofn)
{
    jstatctx_t *ctx = NULL;

    sig_flux_h = h;
    if (signal (SIGINT, sig_handler) == SIG_ERR) 
        return -1;

    ctx = getctx (h);
    ctx->op = (ofn)?  open_test_outfile (ofn) : stdout;

    if (jsc_notify_status (h, job_status_cb, (void *)h) != 0) {
        flux_log (h, LOG_ERR, "failed to reg a job status change CB");
        return -1; 
    }
    if (flux_reactor_run (flux_get_reactor (h), 0) < 0) 
        flux_log (h, LOG_ERR, "error in flux_reactor_run");

    return 0;
}