int module_event_mcast (modhash_t *mh, const flux_msg_t *msg) { const char *topic; zlist_t *uuids; char *uuid; int rc = -1; if (flux_msg_get_topic (msg, &topic) < 0) goto done; if (!(uuids = zhash_keys (mh->zh_byuuid))) oom (); uuid = zlist_first (uuids); while (uuid) { module_t *p = zhash_lookup (mh->zh_byuuid, uuid); assert (p != NULL); if (match_sub (p, topic)) { if (module_sendmsg (p, msg) < 0) goto done; } uuid = zlist_next (uuids); } rc = 0; done: zlist_destroy (&uuids); return rc; }
static int disconnect_update (client_t *c, const flux_msg_t *msg) { char *p; char *key = NULL; char *svc = NULL; const char *topic; uint32_t nodeid; int flags; struct disconnect_notify *d; int rc = -1; if (flux_msg_get_topic (msg, &topic) < 0) goto done; if (flux_msg_get_nodeid (msg, &nodeid, &flags) < 0) goto done; svc = xstrdup (topic); if ((p = strchr (svc, '.'))) *p = '\0'; key = xasprintf ("%s:%u:%d", svc, nodeid, flags); if (!zhash_lookup (c->disconnect_notify, key)) { d = xzmalloc (sizeof (*d)); d->nodeid = nodeid; d->flags = flags; d->topic = xasprintf ("%s.disconnect", svc); zhash_update (c->disconnect_notify, key, d); } rc = 0; done: if (svc) free (svc); if (key) free (key); return rc; }
static void job_state_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { int64_t jobid = -1; json_object *o = NULL; const char *topic = NULL; const char *json_str = NULL; const char *state = NULL; int len = 12; if (flux_msg_get_topic (msg, &topic) < 0) goto done; if (flux_event_decode (msg, NULL, &json_str) < 0 || !(o = Jfromstr (json_str)) || !Jget_int64 (o, "lwj", &jobid)) { flux_log (h, LOG_ERR, "%s: bad message", __FUNCTION__); goto done; } if (strncmp (topic, "jsc", 3) == 0) len = 10; state = topic + len; if (strcmp (state, jsc_job_num2state (J_RESERVED)) == 0) fixup_newjob_event (h, jobid); if (invoke_cbs (h, jobid, get_update_jcb (h, jobid, state), 0) < 0) flux_log (h, LOG_ERR, "job_state_cb: failed to invoke callbacks"); if (job_is_finished (state)) delete_jobinfo (h, jobid); done: return; }
int flux_event_decode (const flux_msg_t *msg, const char **topic, const char **json_str) { int type; const char *ts, *js; int rc = -1; if (msg == NULL) { errno = EINVAL; goto done; } if (flux_msg_get_type (msg, &type) < 0) goto done; if (type != FLUX_MSGTYPE_EVENT) { errno = EPROTO; goto done; } if (flux_msg_get_topic (msg, &ts) < 0) goto done; if (flux_msg_get_payload_json (msg, &js) < 0) goto done; if ((json_str && !js) || (!json_str && js)) { errno = EPROTO; goto done; } if (topic) *topic = ts; if (json_str) *json_str = js; rc = 0; done: return rc; }
/* 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)); }
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++; }
static void profiling_msg_snapshot (flux_t *h, const flux_msg_t *msg, int flags, const char *msg_action) { h = lookup_clone_ancestor (h); cali_id_t attributes[3]; const void * data[3]; size_t size[3]; // This can get called before the handle is really ready if(! h->prof.initialized) return; int len = 0; if (msg_action) { attributes[len] = h->prof.msg_action; data[len] = msg_action; size[len] = strlen(msg_action); ++len; } int type; flux_msg_get_type (msg, &type); const char *msg_type = flux_msg_typestr (type); if (msg_type) { attributes[len] = h->prof.msg_type; data[len] = msg_type; size[len] = strlen(msg_type); ++len; } const char *msg_topic; if (type != FLUX_MSGTYPE_KEEPALIVE) flux_msg_get_topic (msg, &msg_topic); else msg_topic = "NONE"; /* attributes[len] = h->prof.msg_topic; */ /* data[len] = msg_topic; */ /* size[len] = strlen(msg_topic); */ /* ++len; */ if (type == FLUX_MSGTYPE_EVENT) { uint32_t seq; flux_msg_get_seq (msg, &seq); cali_begin_int (h->prof.msg_seq, seq); } cali_push_snapshot (CALI_SCOPE_PROCESS | CALI_SCOPE_THREAD, len /* n_entries */, attributes /* event_attributes */, data /* event_data */, size /* event_size */); if (type == FLUX_MSGTYPE_EVENT) cali_end (h->prof.msg_seq); }
static bool match_substr (zmsg_t *zmsg, const char *topic, const char **rest) { const char *s; if (flux_msg_get_topic (zmsg, &s) < 0) return false; if (strncmp(topic, s, strlen (topic)) != 0) return false; if (rest) *rest = s + strlen (topic); return true; }
static bool subscription_match (client_t *c, const flux_msg_t *msg) { subscription_t *sub; const char *topic; if (flux_msg_get_topic (msg, &topic) < 0) return false; sub = zlist_first (c->subscriptions); while (sub) { if (!strncmp (topic, sub->topic, strlen (sub->topic))) return true; sub = zlist_next (c->subscriptions); } return false; }
int main (int argc, char **argv) { flux_t *h; flux_msg_t *msg; const char *topic; if (!(h = flux_open (NULL, 0))) log_err_exit ("flux_open"); if (flux_event_subscribe (h, "hb") < 0) log_err_exit ("flux_event_subscribe"); if (!(msg = flux_recv (h, FLUX_MATCH_EVENT, 0))) log_err_exit ("flux_recv"); if (flux_msg_get_topic (msg, &topic) < 0) log_err_exit ("flux_msg_get_topic"); printf ("Event: %s\n", topic); if (flux_event_unsubscribe (h, "hb") < 0) log_err_exit ("flux_event_unsubscribe"); flux_msg_destroy (msg); flux_close (h); return (0); }
static void job_state_cb (flux_t *h, flux_msg_handler_t *mh, const flux_msg_t *msg, void *arg) { json_object *jcb = NULL; int64_t jobid = -1; const char *topic = NULL; const char *state = NULL; const char *kvs_path = NULL; int len = 12; if (flux_msg_get_topic (msg, &topic) < 0) goto done; if (flux_event_unpack (msg, NULL, "{ s:I }", "lwj", &jobid) < 0) { flux_log (h, LOG_ERR, "%s: bad message", __FUNCTION__); goto done; } if (!flux_event_unpack (msg, NULL, "{ s:s }", "kvs_path", &kvs_path)) { if (jscctx_add_jobid_path (getctx (h), jobid, kvs_path) < 0) flux_log_error (h, "jscctx_add_jobid_path"); } if (strncmp (topic, "jsc", 3) == 0) len = 10; state = topic + len; if (strcmp (state, jsc_job_num2state (J_RESERVED)) == 0) fixup_newjob_event (h, jobid); if (invoke_cbs (h, jobid, jcb = get_update_jcb (h, jobid, state), 0) < 0) flux_log (h, LOG_ERR, "job_state_cb: failed to invoke callbacks"); if (job_is_finished (state)) delete_jobinfo (h, jobid); done: Jput (jcb); return; }
static void run_cb (flux_t *h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { const char *topic; ctx_t *ctx = (ctx_t *)arg; int *jobid = (int *)malloc (sizeof (int)); if (flux_msg_get_topic (msg, &topic) < 0) { flux_log (h, LOG_ERR, "%s: bad message", __FUNCTION__); free (jobid); return; } // Logging flux_log (h, LOG_DEBUG, "received a request (%s)", topic); // Handle Request sscanf (topic, "sim_exec.run.%d", jobid); zlist_append (ctx->queued_events, jobid); flux_log (h, LOG_DEBUG, "queued the running of jobid %d", *jobid); }
static int event_decode (const flux_msg_t *msg, const char **topic) { int type; const char *ts; int rc = -1; if (msg == NULL) { errno = EINVAL; goto done; } if (flux_msg_get_type (msg, &type) < 0) goto done; if (type != FLUX_MSGTYPE_EVENT) { errno = EPROTO; goto done; } if (flux_msg_get_topic (msg, &ts) < 0) goto done; if (topic) *topic = ts; rc = 0; done: return rc; }
/* 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; }
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; }
static void handle_cb (flux_reactor_t *r, flux_watcher_t *hw, int revents, void *arg) { struct dispatch *d = arg; flux_msg_handler_t *w; flux_msg_t *msg = NULL; int type; if (revents & FLUX_POLLERR) goto fatal; if (!(msg = flux_recv (d->h, FLUX_MATCH_ANY, FLUX_O_NONBLOCK))) { if (errno != EAGAIN && errno != EWOULDBLOCK) goto fatal; else goto done; } if (flux_msg_get_type (msg, &type) < 0) goto done; /* Message matches a coproc that yielded. * Resume, arranging for msg to be returned next by flux_recv(). */ if ((w = find_waiting_handler (d, msg))) { if (flux_requeue (d->h, msg, FLUX_RQ_HEAD) < 0) goto fatal; zlist_remove (d->waiters, w); if (resume_coproc (w) < 0) goto fatal; /* Message matches a handler. * If coproc already running, queue message as backlog. * Else if FLUX_O_COPROC, start coproc. * If coprocs not enabled, call handler directly. */ } else if ((w = find_handler (d, msg))) { if (w->coproc && coproc_started (w->coproc)) { if (backlog_append (w, &msg) < 0) /* msg now property of backlog */ goto fatal; } else if ((flux_flags_get (d->h) & FLUX_O_COPROC)) { if (flux_requeue (d->h, msg, FLUX_RQ_HEAD) < 0) goto fatal; if (start_coproc (w) < 0) goto fatal; } else { w->fn (d->h, w, msg, w->arg); } /* Message matched nothing. * Respond with ENOSYS if it was a request. * Else log it if FLUX_O_TRACE */ } else { if (type == FLUX_MSGTYPE_REQUEST) { if (flux_respond (d->h, msg, ENOSYS, NULL)) goto done; } else if (flux_flags_get (d->h) & FLUX_O_TRACE) { const char *topic = NULL; (void)flux_msg_get_topic (msg, &topic); fprintf (stderr, "nomatch: %s '%s'\n", flux_msg_typestr (type), topic ? topic : ""); } } done: flux_msg_destroy (msg); return; fatal: flux_msg_destroy (msg); flux_reactor_stop_error (r); FLUX_FATAL (d->h); }