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); }
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; }
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; }
int flux_rpc_then (flux_rpc_t *rpc, flux_then_f cb, void *arg) { int rc = -1; assert (rpc->magic == RPC_MAGIC); if (rpc->rx_count >= rpc->rx_expected) { errno = EINVAL; goto done; } if (cb && !rpc->then_cb) { if (!rpc->w) { if (!(rpc->w = flux_msg_handler_create (rpc->h, rpc->m, rpc_cb, rpc))) goto done; } flux_msg_handler_start (rpc->w); if (rpc->rx_msg || rpc->rx_errnum) { if (rpc->rx_msg) if (flux_requeue (rpc->h, rpc->rx_msg, FLUX_RQ_HEAD) < 0) goto done; (void)flux_rpc_next (rpc); } } else if (!cb && rpc->then_cb) { flux_msg_handler_stop (rpc->w); } rpc->then_cb = cb; rpc->then_arg = arg; rc = 0; done: return rc; }
int flux_rpc_then (flux_rpc_t *rpc, flux_then_f cb, void *arg) { int rc = -1; if (rpc->oneway) { errno = EINVAL; goto done; } if (cb && !rpc->then_cb) { if (!rpc->w) { if (!(rpc->w = flux_msg_handler_create (rpc->h, rpc->m, rpc_cb, rpc))) goto done; } flux_msg_handler_start (rpc->w); if (rpc->rx_msg) { if (flux_requeue (rpc->h, rpc->rx_msg, FLUX_RQ_HEAD) < 0) goto done; rpc->rx_msg = NULL; } } else if (!cb && rpc->then_cb) { flux_msg_handler_stop (rpc->w); } rpc->then_cb = cb; rpc->then_arg = arg; rc = 0; done: return rc; }
int ping_initialize (flux_t *h, const char *service) { struct flux_match match = FLUX_MATCH_ANY; struct ping_context *p = calloc (1, sizeof (*p)); if (!p) { errno = ENOMEM; goto error; } match.typemask = FLUX_MSGTYPE_REQUEST; if (asprintf (&match.topic_glob, "%s.ping", service) < 0) { errno = ENOMEM; goto error; } if (!(p->mh = flux_msg_handler_create (h, match, ping_request_cb, p))) goto error; flux_msg_handler_allow_rolemask (p->mh, FLUX_ROLE_ALL); flux_msg_handler_start (p->mh); flux_aux_set (h, "flux::ping", p, ping_finalize); free (match.topic_glob); return 0; error: free (match.topic_glob); if (p) ping_finalize (p); return -1; }
int flux_msg_handler_addvec (flux_t h, struct flux_msg_handler_spec tab[], void *arg) { int i; struct flux_match match = FLUX_MATCH_ANY; for (i = 0; ; i++) { if (!tab[i].typemask && !tab[i].topic_glob && !tab[i].cb) break; /* FLUX_MSGHANDLER_TABLE_END */ match.typemask = tab[i].typemask; match.topic_glob = tab[i].topic_glob; tab[i].w = flux_msg_handler_create (h, match, tab[i].cb, arg); if (!tab[i].w) goto error; flux_msg_handler_start (tab[i].w); } return 0; error: while (i >= 0) { if (tab[i].w) { flux_msg_handler_stop (tab[i].w); flux_msg_handler_destroy (tab[i].w); tab[i].w = NULL; } i--; } return -1; }
static void *cron_event_create (flux_t *h, cron_entry_t *e, json_t *arg) { struct cron_event *ev; int nth = 0; int after = 0; double min_interval = 0.; const char *event; struct flux_match match = FLUX_MATCH_EVENT; if (json_unpack (arg, "{ s:s, s?i, s?i, s?F }", "topic", &event, "nth", &nth, "after", &after, "min_interval", &min_interval) < 0) { flux_log_error (h, "cron event: json_unpack"); errno = EPROTO; return NULL; } if ((ev = calloc (1, sizeof (*ev))) == NULL) { flux_log_error (h, "cron event: calloc"); return NULL; } /* Call subscribe per cron entry. Multiple event subscriptions are * allowed and each cron_event entry will have a corresponding * unsubscribe */ if (flux_event_subscribe (h, event) < 0) { flux_log_error (h, "cron_event: subscribe"); goto fail; } /* Save a copy of this handle for event unsubscribe at destroy */ ev->h = h; ev->nth = nth; ev->after = after; ev->min_interval = min_interval; ev->counter = 0; if ((ev->event = strdup (event)) == NULL) { flux_log_error (h, "cron event: strdup"); goto fail; } match.topic_glob = ev->event; ev->mh = flux_msg_handler_create (h, match, event_handler, (void *)e); if (!ev->mh) { flux_log_error (h, "cron_event: flux_msg_handler_create"); goto fail; } return (ev); fail: cron_event_destroy (ev); return (NULL); }
static void leak_msg_handler (void) { flux_t h; flux_msg_handler_t *w; if (!(h = flux_open ("loop://", 0))) exit (1); if (!(w = flux_msg_handler_create (h, FLUX_MATCH_ANY, dummy, NULL))) exit (1); flux_msg_handler_start (w); flux_close (h); }
static void register_request (ctx_t *ctx, const char *name, flux_msg_handler_f cb) { struct flux_match match = FLUX_MATCH_REQUEST; flux_msg_handler_t *w; match.topic_glob = xasprintf ("%s.%s", module_get_name (ctx->p), name); if (!(w = flux_msg_handler_create (ctx->h, match, cb, ctx->p))) log_err_exit ("flux_msg_handler_create"); flux_msg_handler_start (w); if (zlist_append (ctx->handlers, w) < 0) oom (); free (match.topic_glob); }
void shutdown_set_handle (shutdown_t *s, flux_t h) { struct flux_match match = FLUX_MATCH_EVENT; s->h = h; match.topic_glob = "shutdown"; if (!(s->shutdown = flux_msg_handler_create (s->h, match, shutdown_handler, s))) log_err_exit ("flux_msg_handler_create"); flux_msg_handler_start (s->shutdown); if (flux_event_subscribe (s->h, "shutdown") < 0) log_err_exit ("flux_event_subscribe"); if (flux_get_rank (s->h, &s->myrank) < 0) log_err_exit ("flux_get_rank"); }
static void register_event (ctx_t *ctx, const char *name, flux_msg_handler_f cb) { struct flux_match match = FLUX_MATCH_EVENT; flux_msg_handler_t *w; match.topic_glob = xasprintf ("%s.%s", module_get_name (ctx->p), name); if (!(w = flux_msg_handler_create (ctx->h, match, cb, ctx->p))) log_err_exit ("flux_msg_handler_create"); flux_msg_handler_start (w); if (zlist_append (ctx->handlers, w) < 0) oom (); if (flux_event_subscribe (ctx->h, match.topic_glob) < 0) log_err_exit ("%s: flux_event_subscribe %s", __FUNCTION__, match.topic_glob); free (match.topic_glob); }
static void test_msg (flux_t h) { flux_msg_handler_t *w; int i; ok ((w = flux_msg_handler_create (h, FLUX_MATCH_ANY, msgreader, NULL)) != NULL, "msg: created handler for any message"); flux_msg_handler_start (w); for (i = 0; i < msgwatcher_count; i++) { if (send_request (h, "foo") < 0) break; } ok (i == msgwatcher_count, "msg: sent %d requests", i); ok (flux_reactor_run (flux_get_reactor (h), 0) == 0, "msg: reactor ran to completion after %d requests", msgwatcher_count); flux_msg_handler_stop (w); flux_msg_handler_destroy (w); }