Пример #1
0
/* Return 'n' sequenced responses.
 */
static int nsrc_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    JSON o = Jnew ();
    int i, count;

    if (flux_json_request_decode (*zmsg, &o) < 0) {
        if (flux_err_respond (h, errno, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    if (!Jget_int (o, "count", &count)) {
        if (flux_err_respond (h, EPROTO, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    for (i = 0; i < count; i++) {
        zmsg_t *cpy = zmsg_dup (*zmsg);
        if (!cpy)
            oom ();
        Jadd_int (o, "seq", i);
        if (flux_json_respond (h, o, &cpy) < 0)
            flux_log (h, LOG_ERR, "%s: flux_json_respond: %s", __FUNCTION__,
                      strerror (errno));
        zmsg_destroy (&cpy);
    }
    zmsg_destroy (zmsg);
done:
    Jput (o);
    return 0;
}
Пример #2
0
/* Always return an error 42
 */
static int err_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    if (flux_err_respond (h, 42, zmsg) < 0)
        flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                  strerror (errno));
    return 0;
}
Пример #3
0
static int enter_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    ctx_t *ctx = arg;
    barrier_t *b;
    json_object *o = NULL;
    char *sender = NULL;
    const char *name;
    int count, nprocs, hopcount;

    if (flux_json_request_decode (*zmsg, &o) < 0
     || flux_msg_get_route_first (*zmsg, &sender) < 0
     || util_json_object_get_string (o, "name", &name) < 0
     || util_json_object_get_int (o, "count", &count) < 0
     || util_json_object_get_int (o, "nprocs", &nprocs) < 0) {
        flux_log (ctx->h, LOG_ERR, "%s: ignoring bad message", __FUNCTION__);
        goto done;
    }

    if (!(b = zhash_lookup (ctx->barriers, name)))
        b = barrier_create (ctx, name, nprocs);

    /* Distinguish client (tracked) vs downstream barrier plugin (untracked).
     * A client, distinguished by hopcount > 0, can only enter barrier once.
     */
    if (util_json_object_get_int (o, "hopcount", &hopcount) < 0) {
        if (barrier_add_client (b, sender, zmsg) < 0) {
            flux_err_respond (ctx->h, EEXIST, zmsg);
            flux_log (ctx->h, LOG_ERR,
                        "abort %s due to double entry by client %s",
                        name, sender);
            if (exit_event_send (ctx->h, b->name, ECONNABORTED) < 0)
                flux_log (ctx->h, LOG_ERR, "exit_event_send: %s", strerror (errno));
            goto done;
        }
    }

    /* If the count has been reached, terminate the barrier;
     * o/w set timer to pass count upstream and zero it here.
     */
    b->count += count;
    if (b->count == b->nprocs) {
        if (exit_event_send (ctx->h, b->name, 0) < 0)
            flux_log (ctx->h, LOG_ERR, "exit_event_send: %s", strerror (errno));
    } else if (ctx->rank > 0 && !ctx->timer_armed) {
        if (flux_tmouthandler_add (h, barrier_reduction_timeout_msec,
                                   true, timeout_cb, ctx) < 0) {
            flux_log (h, LOG_ERR, "flux_tmouthandler_add: %s",strerror (errno));
            goto done;
        }
        ctx->timer_armed = true;
    }
done:
    if (o)
        json_object_put (o);
    if (*zmsg)
        zmsg_destroy (zmsg);
    if (sender)
        free (sender);
    return 0;
}
Пример #4
0
/* Reply to all queued requests.
 */
static int flush_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    ctx_t *ctx = getctx (h);
    zmsg_t *z;

    while ((z = zlist_pop (ctx->clog_requests))) {
        /* send clog response */
        if (flux_err_respond (h, 0, &z) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                          strerror (errno));
    }
    /* send flush response */
    if (flux_err_respond (h, 0, zmsg) < 0)
        flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
    return 0;
}
Пример #5
0
static int hi_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    if (flux_err_respond (h, 0, zmsg) < 0) {
        flux_log (h, LOG_ERR, "%s: responding: %s", __FUNCTION__,
                  strerror (errno));
        return -1;
    }
    return 0;
}
Пример #6
0
static int send_enter_response (const char *key, void *item, void *arg)
{
    zmsg_t *zmsg = item;
    barrier_t *b = arg;
    zmsg_t *cpy;

    if (!(cpy = zmsg_dup (zmsg)))
        oom ();
    flux_err_respond (b->ctx->h, b->errnum, &cpy);
    return 0;
}
Пример #7
0
/* Proxy ping.
 */
static int xping_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    ctx_t *ctx = arg;
    int rank, seq = ctx->ping_seq++;
    const char *service;
    char *hashkey = NULL;
    JSON in = Jnew ();
    JSON o = NULL;

    if (flux_json_request_decode (*zmsg, &o) < 0) {
        if (flux_err_respond (h, errno, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    if (!Jget_int (o, "rank", &rank) || !Jget_str (o, "service", &service)) {
        if (flux_err_respond (h, EPROTO, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    flux_log (h, LOG_DEBUG, "Rxping rank=%d service=%s", rank, service);

    Jadd_int (in, "seq", seq);
    flux_log (h, LOG_DEBUG, "Tping seq=%d %d!%s", seq, rank, service);
    if (flux_json_request (h, rank, 0, service, in) < 0) {
        if (flux_err_respond (h, errno, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    hashkey = xasprintf ("%d", seq);
    zhash_update (ctx->ping_requests, hashkey, *zmsg);
    *zmsg = NULL;
done:
    Jput (o);
    Jput (in);
    if (hashkey)
        free (hashkey);
    return 0;
}
Пример #8
0
/* The req.clog request will not be answered until req.flush is called.
 */
static int stuck_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    if (flux_json_rpc (h, FLUX_NODEID_ANY, "req.clog", NULL, NULL) < 0) {
        flux_log (h, LOG_ERR, "%s: req.clog RPC: %s", __FUNCTION__,
                  strerror (errno));
        return -1;
    }
    if (flux_err_respond (h, 0, zmsg) < 0) {
        flux_log (h, LOG_ERR, "%s: responding: %s", __FUNCTION__,
                  strerror (errno));
        return -1;
    }
    return 0;
}
Пример #9
0
/* Accept a json payload, verify it and return error if it doesn't
 * match expected.
 */
static int sink_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    JSON o = NULL;
    double d;

    if (flux_json_request_decode (*zmsg, &o) < 0) {
        if (flux_err_respond (h, errno, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    if (!Jget_double (o, "pi", &d) || d != 3.14) {
        if (flux_err_respond (h, EPROTO, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    if (flux_err_respond (h, 0, zmsg) < 0)
        flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                  strerror (errno));
done:
    Jput (o);
    return 0;
}
Пример #10
0
/* Echo a json payload back to requestor.
 */
static int echo_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    JSON o = NULL;

    if (flux_json_request_decode (*zmsg, &o) < 0) {
        if (flux_err_respond (h, errno, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    if (flux_json_respond (h, o, zmsg) < 0) {
        flux_log (h, LOG_ERR, "%s: flux_json_respond: %s", __FUNCTION__,
                  strerror (errno));
        goto done;
    }
done:
    Jput (o);
    return 0;
}
Пример #11
0
/* Handle the simplest possible request.
 * Verify that everything is as expected; log it and stop the reactor if not.
 */
static int null_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    //ctx_t *ctx = arg;
    const char *topic;
    int type, size, flags;
    int rc = -1;
    void *buf;
    uint32_t nodeid;

    if (!zmsg || !*zmsg) {
        flux_log (h, LOG_ERR, "%s: got NULL zmsg!", __FUNCTION__);
        goto done;
    }
    if (flux_msg_get_type (*zmsg, &type) < 0) {
        flux_log (h, LOG_ERR, "%s: flux_msg_get_type: %s", __FUNCTION__,
                  strerror (errno));
        goto done;
    }
    if (type != FLUX_MSGTYPE_REQUEST) {
        flux_log (h, LOG_ERR, "%s: unexpected type %s", __FUNCTION__,
                  flux_msg_typestr (type));
        goto done;
    }
    if (flux_msg_get_nodeid (*zmsg, &nodeid, &flags) < 0) {
        flux_log (h, LOG_ERR, "%s: flux_msg_get_nodeid: %s", __FUNCTION__,
                  strerror (errno));
        goto done;
    }
    if (nodeid != FLUX_NODEID_ANY && nodeid != flux_rank (h)) {
        flux_log (h, LOG_ERR, "%s: unexpected nodeid: %"PRIu32"", __FUNCTION__,
                  nodeid);
        goto done;
    }
    if (flux_msg_get_topic (*zmsg, &topic) < 0) {
        flux_log (h, LOG_ERR, "%s: flux_msg_get_topic: %s", __FUNCTION__,
                  strerror (errno));
        goto done;
    }
    if (strcmp (topic, "req.null") != 0) {
        flux_log (h, LOG_ERR, "%s: unexpected topic: %s", __FUNCTION__,
                  topic);
        goto done;
    }
    if (flux_msg_get_payload (*zmsg, &flags, &buf, &size) == 0) {
        flux_log (h, LOG_ERR, "%s: unexpected payload size %d", __FUNCTION__,
                  size);
        goto done;
    }
    if (errno != EPROTO) {
        flux_log (h, LOG_ERR, "%s: get nonexistent payload: %s", __FUNCTION__,
                  strerror (errno));
        goto done;
    }
    errno = 0;
    if (flux_err_respond (h, 0, zmsg) < 0) {
        flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                  strerror (errno));
        goto done;
    }
    rc = 0;
done:
    return rc;
}
Пример #12
0
static int job_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    const char *json_str;
    json_object *o = NULL;
    const char *topic;

    if (flux_msg_get_topic (*zmsg, &topic) < 0)
        goto out;
    if (flux_msg_get_payload_json (*zmsg, &json_str) < 0)
        goto out;
    if (json_str && !(o = json_tokener_parse (json_str)))
        goto out;
    if (strcmp (topic, "job.shutdown") == 0) {
        flux_reactor_stop (h);
    }
    if (strcmp (topic, "job.next-id") == 0) {
        if (flux_rank (h) == 0) {
            unsigned long id = lwj_next_id (h);
            json_object *ox = json_id (id);
            flux_json_respond (h, ox, zmsg);
            json_object_put (o);
        }
        else {
            fprintf (stderr, "%s: forwarding request\n", topic);
            flux_json_request (h, FLUX_NODEID_ANY,
                                  FLUX_MATCHTAG_NONE, topic, o);
        }
    }
    if (strcmp (topic, "job.create") == 0) {
        json_object *jobinfo = NULL;
        unsigned long id = lwj_next_id (h);
        bool should_workaround = false;

        //"Fix" for Race Condition
        if (util_json_object_get_boolean (o, "race_workaround",
                                           &should_workaround) < 0) {
            should_workaround = false;
        } else if (should_workaround) {
            if (wait_for_lwj_watch_init (h, id) < 0) {
              flux_err_respond (h, errno, zmsg);
              goto out;
            }
        }

        int rc = kvs_job_new (h, id);
        if (rc < 0) {
            flux_err_respond (h, errno, zmsg);
            goto out;
        }
        add_jobinfo (h, id, o);

        kvs_commit (h);

        /* Generate reply with new jobid */
        jobinfo = util_json_object_new_object ();
        util_json_object_add_int64 (jobinfo, "jobid", id);
        flux_json_respond (h, jobinfo, zmsg);
        json_object_put (jobinfo);
    }

out:
    if (o)
        json_object_put (o);
    zmsg_destroy (zmsg);
    return 0;
}