static int64_t next_jobid (flux_t h) { int64_t ret = (int64_t) -1; const char *json_str; json_object *req, *resp; flux_rpc_t *rpc; req = Jnew (); Jadd_str (req, "name", "lwj"); Jadd_int64 (req, "preincrement", 1); Jadd_int64 (req, "postincrement", 0); Jadd_bool (req, "create", true); rpc = flux_rpc (h, "cmb.seq.fetch", json_object_to_json_string (req), 0, 0); json_object_put (req); if ((flux_rpc_get (rpc, NULL, &json_str) < 0) || !(resp = json_tokener_parse (json_str))) { flux_log_error (h, "rpc_get"); goto out; } Jget_int64 (resp, "value", &ret); json_object_put (resp); out: flux_rpc_destroy (rpc); return ret; }
/* * Free parsed JSON object and RPC for hwloc toplogy */ static void hwloc_topo_destroy (struct hwloc_topo *t) { json_object_put (t->o); flux_rpc_destroy (t->rpc); flux_close (t->h); free (t); }
static int internal_content_store (optparse_t *p, int ac, char *av[]) { const uint32_t blob_size_limit = 1048576; /* RFC 10 */ uint8_t *data; int size; flux_t *h; flux_rpc_t *rpc; const char *topic; if (optparse_optind (p) != ac) { optparse_print_usage (p); exit (1); } if ((size = read_all (STDIN_FILENO, &data)) < 0) log_err_exit ("read"); if (!(h = builtin_get_flux_handle (p))) log_err_exit ("flux_open"); if (optparse_hasopt (p, "dry-run")) { int flags; const char *hashfun; if (size > blob_size_limit) log_errn_exit (EFBIG, "content-store"); if (!(hashfun = flux_attr_get (h, "content-hash", &flags))) log_err_exit ("flux_attr_get content-hash"); if (!strcmp (hashfun, "sha1")) { uint8_t hash[SHA1_DIGEST_SIZE]; char hashstr[SHA1_STRING_SIZE]; SHA1_CTX sha1_ctx; SHA1_Init (&sha1_ctx); SHA1_Update (&sha1_ctx, (uint8_t *)data, size); SHA1_Final (&sha1_ctx, hash); sha1_hashtostr (hash, hashstr); printf ("%s\n", hashstr); } else log_msg_exit ("content-store: unsupported hash function: %s", hashfun); } else { const char *blobref; int blobref_size; if (optparse_hasopt (p, "bypass-cache")) topic = "content-backing.store"; else topic = "content.store"; if (!(rpc = flux_rpc_raw (h, topic, data, size, 0, 0))) log_err_exit ("%s", topic); if (flux_rpc_get_raw (rpc, &blobref, &blobref_size) < 0) log_err_exit ("%s", topic); if (!blobref || blobref[blobref_size - 1] != '\0') log_msg_exit ("%s: protocol error", topic); printf ("%s\n", blobref); flux_rpc_destroy (rpc); } flux_close (h); free (data); return (0); }
/* Handle responses */ void ping_continuation (flux_rpc_t *rpc, void *arg) { struct ping_ctx *ctx = arg; const char *json_str, *route, *pad; int64_t sec, nsec; struct timespec t0; int seq; json_object *out = NULL; struct ping_data *pdata = flux_rpc_aux_get (rpc); tstat_t *tstat = pdata->tstat; if (flux_rpc_get (rpc, &json_str) < 0) { log_err ("flux_rpc_get"); goto done; } if (!(out = Jfromstr (json_str)) || !Jget_int (out, "seq", &seq) || !Jget_int64 (out, "time.tv_sec", &sec) || !Jget_int64 (out, "time.tv_nsec", &nsec) || !Jget_str (out, "pad", &pad) || !Jget_str (out, "route", &route) || strcmp (ctx->pad, pad) != 0) { log_err ("error decoding ping response"); goto done; } t0.tv_sec = sec; t0.tv_nsec = nsec; tstat_push (tstat, monotime_since (t0)); pdata->seq = seq; if (pdata->route) free (pdata->route); pdata->route = xstrdup (route); pdata->rpc_count++; done: if (flux_rpc_next (rpc) < 0 && pdata->rpc_count) { if (ctx->rank != NULL) { printf ("%s!%s pad=%lu seq=%d time=(%0.3f:%0.3f:%0.3f) ms stddev %0.3f\n", ctx->rank, ctx->topic, strlen (ctx->pad), pdata->seq, tstat_min (tstat), tstat_mean (tstat), tstat_max (tstat), tstat_stddev (tstat)); } else { char s[16]; snprintf (s, sizeof (s), "%u", ctx->nodeid); printf ("%s%s%s pad=%lu seq=%d time=%0.3f ms (%s)\n", ctx->nodeid == FLUX_NODEID_ANY ? "" : s, ctx->nodeid == FLUX_NODEID_ANY ? "" : "!", ctx->topic, strlen (ctx->pad), pdata->seq, tstat_mean (tstat), pdata->route); } flux_rpc_destroy (rpc); } Jput (out); }
/* Proxy ping. */ void xping_request_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { ctx_t *ctx = arg; const char *json_str; int saved_errno; int rank, seq = ctx->ping_seq++; const char *service; char *hashkey = NULL; JSON in = Jnew (); JSON o = NULL; flux_msg_t *cpy; if (flux_request_decode (msg, NULL, &json_str) < 0) { saved_errno = errno; goto error; } if (!(o = Jfromstr (json_str)) || !Jget_int (o, "rank", &rank) || !Jget_str (o, "service", &service)) { saved_errno = errno = EPROTO; goto error; } 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); flux_rpc_t *rpc; if (!(rpc = flux_rpc (h, service, Jtostr (in), rank, FLUX_RPC_NORESPONSE))) { saved_errno = errno; goto error; } flux_rpc_destroy (rpc); if (!(cpy = flux_msg_copy (msg, true))) { saved_errno = errno; goto error; } hashkey = xasprintf ("%d", seq); zhash_update (ctx->ping_requests, hashkey, cpy); zhash_freefn (ctx->ping_requests, hashkey, (zhash_free_fn *)flux_msg_destroy); Jput (o); Jput (in); if (hashkey) free (hashkey); return; error: if (flux_respond (h, msg, saved_errno, NULL) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); Jput (o); Jput (in); }
int main (int argc, char **argv) { flux_t h; flux_rpc_t *rpc; if (!(h = flux_open (NULL, 0))) err_exit ("flux_open"); if (!(rpc = flux_rpc (h, "cmb.info", NULL, FLUX_NODEID_ANY, 0))) err_exit ("flux_rpc"); get_rank (rpc); flux_rpc_destroy (rpc); flux_close (h); return (0); }
flux_rpc_t *flux_rpc (flux_t h, const char *topic, const char *json_str, uint32_t nodeid, int flags) { flux_rpc_t *rpc = rpc_create (h, flags, 1); if (rpc_request_send (rpc, 0, topic, json_str, nodeid) < 0) goto error; if (!rpc->oneway) rpc->nodemap[0] = nodeid; return rpc; error: flux_rpc_destroy (rpc); return NULL; }
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); }
void mod_insmod (flux_t h, opt_t opt) { char *modpath = NULL; char *modname = NULL; if (opt.argc < 1) usage (); if (strchr (opt.argv[0], '/')) { if (!(modpath = realpath (opt.argv[0], NULL))) oom (); if (!(modname = flux_modname (modpath))) msg_exit ("%s", dlerror ()); } else { char *searchpath = getenv ("FLUX_MODULE_PATH"); if (!searchpath) searchpath = MODULE_PATH; modname = xstrdup (opt.argv[0]); if (!(modpath = flux_modfind (searchpath, modname))) msg_exit ("%s: not found in module search path", modname); } opt.argv++; opt.argc--; if (opt.direct) { char *service = getservice (modname); char *topic = xasprintf ("%s.insmod", service); char *json_str = flux_insmod_json_encode (modpath, opt.argc, opt.argv); assert (json_str != NULL); flux_rpc_t *r = flux_rpc_multi (h, topic, json_str, opt.nodeset, 0); if (!r) err_exit ("%s", topic); while (!flux_rpc_completed (r)) { uint32_t nodeid = FLUX_NODEID_ANY; if (flux_rpc_get (r, NULL, NULL) < 0) err_exit ("%s[%d]", topic, nodeid == FLUX_NODEID_ANY ? -1 : nodeid); } flux_rpc_destroy (r); free (topic); free (service); free (json_str); } else { if (flux_modctl_load (h, opt.nodeset, modpath, opt.argc, opt.argv) < 0) err_exit ("%s", modname); } if (modpath) free (modpath); if (modname) free (modname); }
static void store_completion (flux_rpc_t *rpc, void *arg) { flux_reactor_t *r = arg; const char *blobref; int blobref_size; if (flux_rpc_get_raw (rpc, &blobref, &blobref_size) < 0) log_err_exit ("store"); if (!blobref || blobref[blobref_size - 1] != '\0') log_msg_exit ("store: protocol error"); //printf ("%s\n", blobref); flux_rpc_destroy (rpc); if (--spam_cur_inflight < spam_max_inflight/2) flux_reactor_stop (r); }
static int dmesg_clear (flux_t *h, int seq) { flux_rpc_t *rpc; int rc = -1; if (!(rpc = flux_rpcf (h, "cmb.dmesg.clear", FLUX_NODEID_ANY, 0, "{s:i}", "seq", seq))) goto done; if (flux_rpc_get (rpc, NULL) < 0) goto done; rc = 0; done: flux_rpc_destroy (rpc); return rc; }
flux_rpc_t *flux_rpc_multi (flux_t h, const char *topic, const char *json_str, const char *nodeset, int flags) { nodeset_t *ns = NULL; nodeset_iterator_t *itr = NULL; flux_rpc_t *rpc = NULL; int i; uint32_t count; if (!topic || !nodeset) { errno = EINVAL; goto error; } if (!strcmp (nodeset, "all")) { if (flux_get_size (h, &count) < 0) goto error; ns = nodeset_create_range (0, count - 1); } else { if ((ns = nodeset_create_string (nodeset))) count = nodeset_count (ns); } if (!ns) { errno = EINVAL; goto error; } if (!(rpc = rpc_create (h, flags, count))) goto error; if (!(itr = nodeset_iterator_create (ns))) goto error; for (i = 0; i < count; i++) { uint32_t nodeid = nodeset_next (itr); assert (nodeid != NODESET_EOF); if (rpc_request_send (rpc, i, topic, json_str, nodeid) < 0) goto error; if (!rpc->oneway) rpc->nodemap[i] = nodeid; } nodeset_iterator_destroy (itr); return rpc; error: if (rpc) flux_rpc_destroy (rpc); if (itr) nodeset_iterator_destroy (itr); if (ns) nodeset_destroy (ns); return NULL; }
static int internal_heaptrace_stop (optparse_t *p, int ac, char *av[]) { flux_t *h; flux_rpc_t *rpc; if (optparse_optind (p) != ac) { optparse_print_usage (p); exit (1); } if (!(h = builtin_get_flux_handle (p))) log_err_exit ("flux_open"); if (!(rpc = flux_rpc (h, "cmb.heaptrace.stop", NULL, FLUX_NODEID_ANY, 0)) || flux_rpc_get (rpc, NULL) < 0) log_err_exit ("cmb.heaptrace.stop"); flux_rpc_destroy (rpc); flux_close (h); return (0); }
static int op_event_unsubscribe (void *impl, const char *topic) { ctx_t *c = impl; assert (c->magic == CTX_MAGIC); flux_rpc_t *rpc = NULL; JSON in = Jnew (); int rc = 0; Jadd_str (in, "topic", topic); if (!(rpc = flux_rpc (c->h, "local.unsub", Jtostr (in), FLUX_NODEID_ANY, 0)) || flux_rpc_get (rpc, NULL, NULL) < 0) goto done; rc = 0; done: flux_rpc_destroy (rpc); Jput (in); return rc; }
static int dmesg_clear (flux_t h, int seq) { flux_rpc_t *rpc; JSON o = Jnew (); int rc = -1; Jadd_int (o, "seq", seq); if (!(rpc = flux_rpc (h, "cmb.dmesg.clear", Jtostr (o), FLUX_NODEID_ANY, 0))) goto done; if (flux_rpc_get (rpc, NULL, NULL) < 0) goto done; rc = 0; done: flux_rpc_destroy (rpc); Jput (o); return rc; }
static void request_hwloc_reload (flux_t h, const char *nodeset) { flux_rpc_t *rpc; if (!(rpc = flux_rpc_multi (h, "resource-hwloc.reload", NULL, nodeset, 0))) err_exit ("flux_rpc_multi"); while (!flux_rpc_completed (rpc)) { const char *json_str; uint32_t nodeid = FLUX_NODEID_ANY; if (flux_rpc_get (rpc, &nodeid, &json_str) < 0) { if (nodeid == FLUX_NODEID_ANY) err ("flux_rpc_get"); else err ("rpc(%"PRIu32")", nodeid); } } flux_rpc_destroy (rpc); }
void flux_vlog (flux_t *h, int level, const char *fmt, va_list ap) { logctx_t *ctx = getctx (h); int saved_errno = errno; uint32_t rank; flux_rpc_t *rpc = NULL; int n, len; char timestamp[WALLCLOCK_MAXLEN]; char hostname[STDLOG_MAX_HOSTNAME + 1]; struct stdlog_header hdr; stdlog_init (&hdr); hdr.pri = STDLOG_PRI (level, LOG_USER); if (wallclock_get_zulu (timestamp, sizeof (timestamp)) >= 0) hdr.timestamp = timestamp; if (flux_get_rank (h, &rank) == 0) { snprintf (hostname, sizeof (hostname), "%" PRIu32, rank); hdr.hostname = hostname; } hdr.appname = ctx->appname; hdr.procid = ctx->procid; len = stdlog_encode (ctx->buf, sizeof (ctx->buf), &hdr, STDLOG_NILVALUE, ""); assert (len < sizeof (ctx->buf)); n = vsnprintf (ctx->buf + len, sizeof (ctx->buf) - len, fmt, ap); if (n > sizeof (ctx->buf) - len) /* ignore truncation of message */ n = sizeof (ctx->buf) - len; len += n; if (ctx->cb) { ctx->cb (ctx->buf, len, ctx->cb_arg); } else { if (!(rpc = flux_rpc_raw (h, "cmb.log", ctx->buf, len, FLUX_NODEID_ANY, FLUX_RPC_NORESPONSE))) goto done; } done: flux_rpc_destroy (rpc); errno = saved_errno; }
static int internal_content_dropcache (optparse_t *p, int ac, char *av[]) { flux_t *h; flux_rpc_t *rpc = NULL; const char *topic = "content.dropcache"; if (optparse_optind (p) != ac) { optparse_print_usage (p); exit (1); } if (!(h = builtin_get_flux_handle (p))) log_err_exit ("flux_open"); if (!(rpc = flux_rpc (h, topic, NULL, FLUX_NODEID_ANY, 0))) log_err_exit ("%s", topic); if (flux_rpc_get (rpc, NULL) < 0) log_err_exit ("%s", topic); flux_rpc_destroy (rpc); flux_close (h); return (0); }
static void send_enter_request (ctx_t *ctx, barrier_t *b) { json_object *o = Jnew (); flux_rpc_t *rpc; Jadd_str (o, "name", b->name); Jadd_int (o, "count", b->count); Jadd_int (o, "nprocs", b->nprocs); Jadd_int (o, "hopcount", 1); if (!(rpc = flux_rpc (ctx->h, "barrier.enter", Jtostr (o), FLUX_NODEID_UPSTREAM, FLUX_RPC_NORESPONSE))) { flux_log_error (ctx->h, "sending barrier.enter request"); goto done; } done: if (rpc) flux_rpc_destroy (rpc); json_object_put (o); }
static int op_event_unsubscribe (void *impl, const char *topic) { ctx_t *ctx = impl; assert (ctx->magic == MODHANDLE_MAGIC); JSON in = Jnew (); flux_rpc_t *rpc = NULL; int rc = -1; if (connect_socket (ctx) < 0) goto done; Jadd_str (in, "topic", topic); if (!(rpc = flux_rpc (ctx->h, "cmb.unsub", Jtostr (in), FLUX_NODEID_ANY, 0)) || flux_rpc_get (rpc, NULL, NULL) < 0) goto done; rc = 0; done: Jput (in); flux_rpc_destroy (rpc); return rc; }
static flux_rpc_t *rpc_create (flux_t h, int flags, int count) { flux_rpc_t *rpc = xzmalloc (sizeof (*rpc)); if ((flags & FLUX_RPC_NORESPONSE)) { rpc->oneway = true; rpc->m.matchtag = FLUX_MATCHTAG_NONE; } else { rpc->nodemap = xzmalloc (sizeof (rpc->nodemap[0]) * count); rpc->m.matchtag = flux_matchtag_alloc (h, count); if (rpc->m.matchtag == FLUX_MATCHTAG_NONE) { flux_rpc_destroy (rpc); return NULL; } } rpc->m.bsize = count; rpc->m.typemask = FLUX_MSGTYPE_RESPONSE; rpc->h = h; rpc->usecount = 1; return rpc; }
static int internal_heaptrace_dump (optparse_t *p, int ac, char *av[]) { flux_t *h; flux_rpc_t *rpc; json_object *in = Jnew (); if (optparse_optind (p) != ac - 1) { optparse_print_usage (p); exit (1); } Jadd_str (in, "reason", av[ac - 1]); if (!(h = builtin_get_flux_handle (p))) log_err_exit ("flux_open"); if (!(rpc = flux_rpc (h, "cmb.heaptrace.dump", Jtostr (in), FLUX_NODEID_ANY, 0)) || flux_rpc_get (rpc, NULL) < 0) log_err_exit ("cmb.heaptrace.dump"); flux_rpc_destroy (rpc); flux_close (h); return (0); }
int get_watch_stats (flux_t *h, int *count) { flux_rpc_t *rpc; const char *json_str; json_object *o = NULL; int rc = -1; if (!(rpc = flux_rpc (h, "kvs.stats.get", NULL, FLUX_NODEID_ANY, 0))) goto done; if (flux_rpc_get (rpc, &json_str) < 0) goto done; if (!(o = Jfromstr (json_str)) || !Jget_int (o, "#watchers", count)) { errno = EPROTO; goto done; } rc = 0; done: flux_rpc_destroy (rpc); Jput (o); return rc; }
int rpctest_begin_cb (flux_t h, int type, zmsg_t **zmsg, void *arg) { uint32_t nodeid; int i, errors; int old_count; flux_rpc_t *r; const char *json_str; errno = 0; ok (!(r = flux_rpc_multi (h, NULL, "foo", "all", 0)) && errno == EINVAL, "flux_rpc_multi [0] with NULL topic fails with EINVAL"); errno = 0; ok (!(r = flux_rpc_multi (h, "bar", "foo", NULL, 0)) && errno == EINVAL, "flux_rpc_multi [0] with NULL nodeset fails with EINVAL"); errno = 0; ok (!(r = flux_rpc_multi (h, "bar", "foo", "xyz", 0)) && errno == EINVAL, "flux_rpc_multi [0] with bad nodeset fails with EINVAL"); /* working no-payload RPC */ old_count = hello_count; ok ((r = flux_rpc_multi (h, "rpctest.hello", NULL, "all", 0)) != NULL, "flux_rpc_multi [0] with no payload when none is expected works"); if (!r) BAIL_OUT ("can't continue without successful rpc call"); ok (flux_rpc_check (r) == false, "flux_rpc_check says get would block"); ok (flux_rpc_get (r, NULL, NULL) == 0, "flux_rpc_get works"); ok (hello_count == old_count + 1, "rpc was called once"); flux_rpc_destroy (r); /* cause remote EPROTO (unexpected payload) - picked up in _get() */ ok ((r = flux_rpc_multi (h, "rpctest.hello", "foo", "all", 0)) != NULL, "flux_rpc_multi [0] with unexpected payload works, at first"); ok (flux_rpc_check (r) == false, "flux_rpc_check says get would block"); errno = 0; ok (flux_rpc_get (r, NULL, NULL) < 0 && errno == EPROTO, "flux_rpc_get fails with EPROTO"); flux_rpc_destroy (r); /* fake that we have a larger session */ fake_size = 128; char s[16]; uint32_t size = 0; snprintf (s, sizeof (s), "%u", fake_size); flux_attr_fake (h, "size", s, FLUX_ATTRFLAG_IMMUTABLE); flux_get_size (h, &size); cmp_ok (size, "==", fake_size, "successfully faked flux_get_size() of %d", fake_size); /* repeat working no-payload RPC test (now with 128 nodes) */ old_count = hello_count; ok ((r = flux_rpc_multi (h, "rpctest.hello", NULL, "all", 0)) != NULL, "flux_rpc_multi [0-%d] with no payload when none is expected works", fake_size - 1); ok (flux_rpc_check (r) == false, "flux_rpc_check says get would block"); errors = 0; for (i = 0; i < fake_size; i++) if (flux_rpc_get (r, NULL, NULL) < 0) errors++; ok (errors == 0, "flux_rpc_get succeded %d times", fake_size); cmp_ok (hello_count - old_count, "==", fake_size, "rpc was called %d times", fake_size); flux_rpc_destroy (r); /* same with a subset */ old_count = hello_count; ok ((r = flux_rpc_multi (h, "rpctest.hello", NULL, "[0-63]", 0)) != NULL, "flux_rpc_multi [0-%d] with no payload when none is expected works", 64 - 1); ok (flux_rpc_check (r) == false, "flux_rpc_check says get would block"); errors = 0; for (i = 0; i < 64; i++) if (flux_rpc_get (r, &nodeid, NULL) < 0 || nodeid != i) errors++; ok (errors == 0, "flux_rpc_get succeded %d times, with correct nodeid map", 64); cmp_ok (hello_count - old_count, "==", 64, "rpc was called %d times", 64); flux_rpc_destroy (r); /* same with echo payload */ ok ((r = flux_rpc_multi (h, "rpctest.echo", "foo", "[0-63]", 0)) != NULL, "flux_rpc_multi [0-%d] ok", 64 - 1); ok (flux_rpc_check (r) == false, "flux_rpc_check says get would block"); errors = 0; for (i = 0; i < 64; i++) { if (flux_rpc_get (r, NULL, &json_str) < 0 || !json_str || strcmp (json_str, "foo") != 0) errors++; } ok (errors == 0, "flux_rpc_get succeded %d times, with correct return payload", 64); flux_rpc_destroy (r); /* detect partial failure without mresponse */ nodeid_fake_error = 20; ok ((r = flux_rpc_multi (h, "rpctest.nodeid", NULL, "[0-63]", 0)) != NULL, "flux_rpc_multi [0-%d] ok", 64 - 1); ok (flux_rpc_check (r) == false, "flux_rpc_check says get would block"); for (i = 0; i < 64; i++) { if (flux_rpc_get (r, &nodeid, &json_str) < 0) break; } ok (i == 20 && errno == EPERM, "flux_rpc_get correctly reports single error"); flux_rpc_destroy (r); /* test _then (still at fake session size of 128) */ ok ((then_r = flux_rpc_multi (h, "rpctest.hello", NULL, "[0-127]", 0)) != NULL, "flux_rpc_multi [0-127] ok"); ok (flux_rpc_then (then_r, then_cb, h) == 0, "flux_rpc_then works"); /* then_cb stops reactor; results reported, then_r destroyed in main() */ return 0; }
flux_rpc_t *flux_rpc_multi (flux_t *h, const char *topic, const char *json_str, const char *nodeset, int flags) { nodeset_t *ns = NULL; nodeset_iterator_t *itr = NULL; flux_rpc_t *rpc = NULL; int i; uint32_t count; int rx_expected; if (!topic || !nodeset) { errno = EINVAL; goto error; } if (!strcmp (nodeset, "all")) { if (flux_get_size (h, &count) < 0) goto error; ns = nodeset_create_range (0, count - 1); } else { if ((ns = nodeset_create_string (nodeset))) count = nodeset_count (ns); } if (!ns) { errno = EINVAL; goto error; } rx_expected = count; if ((flags & FLUX_RPC_NORESPONSE)) rx_expected = 0; if (!(rpc = rpc_create (h, rx_expected))) goto error; if (!(itr = nodeset_iterator_create (ns))) goto error; #if HAVE_CALIPER cali_begin_string_byname ("flux.message.rpc", "multi"); cali_begin_int_byname ("flux.message.response_expected", !(flags & FLUX_RPC_NORESPONSE)); #endif for (i = 0; i < count; i++) { uint32_t nodeid = nodeset_next (itr); assert (nodeid != NODESET_EOF); #if HAVE_CALIPER cali_begin_int_byname ("flux.message.rpc.nodeid", nodeid); #endif if (rpc_request_send (rpc, topic, nodeid, json_str) < 0) goto error; #if HAVE_CALIPER cali_end_byname ("flux.message.rpc.nodeid"); #endif } #if HAVE_CALIPER cali_end_byname ("flux.message.response_expected"); cali_end_byname ("flux.message.rpc"); #endif nodeset_iterator_destroy (itr); return rpc; error: if (rpc) flux_rpc_destroy (rpc); if (itr) nodeset_iterator_destroy (itr); if (ns) nodeset_destroy (ns); return NULL; }
int main (int argc, char *argv[]) { flux_msg_t *msg; flux_t h; plan (33); (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"); flux_fatal_set (h, fatal_err, NULL); ok (flux_msg_watcher_addvec (h, htab, 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, "encoded rpctest.begin request OK"); ok (flux_send (h, msg, 0) == 0, "sent rpctest.begin request"); ok (flux_reactor_start (h) == 0, "reactor completed normally"); flux_msg_destroy (msg); /* test _then: Slightly tricky. * Send request. We're not in a coproc ctx here in main(), so there * will be no response, therefore, check will be false. Register * continuation, start reactor. Response will be received, continuation * will be invoked. Continuation stops the reactor. */ flux_rpc_t *r; ok ((r = flux_rpc (h, "rpctest.echo", "xxx", FLUX_NODEID_ANY, 0)) != NULL, "flux_rpc with payload when payload is expected works"); ok (flux_rpc_check (r) == false, "flux_rpc_check says get would block"); /* reg/unreg _then a couple times for fun */ ok (flux_rpc_then (r, NULL, 0) == 0, "flux_rpc_then with NULL cb works"); ok (flux_rpc_then (r, then_cb, h) == 0, "flux_rpc_then works after NULL"); ok (flux_rpc_then (r, NULL, 0) == 0, "flux_rpc_then with NULL cb after non-NULL works"); ok (flux_rpc_then (r, then_cb, h) == 0, "flux_rpc_then works"); /* enough of that */ ok (flux_reactor_start (h) == 0, "reactor completed normally"); flux_rpc_destroy (r); /* Test a _then corner case: * If _check() is called before _then(), a message may have been cached * in the flux_rpc_t. rpctest_thenbug_cb creates this condition. * Next, _then continuation is installed, but will reactor call it? * This will hang if rpc implementation doesn't return a cached message * back to the handle in _then(). Else, continuation will stop reactor. */ ok ((thenbug_r = flux_rpc (h, "rpctest.echo", "xxx", FLUX_NODEID_ANY, 0)) != NULL, "thenbug: sent echo request"); do { if (!(msg = flux_request_encode ("rpctest.thenbug", NULL)) || flux_send (h, msg, 0) < 0 || flux_reactor_start (h) < 0) { flux_msg_destroy (msg); break; } flux_msg_destroy (msg); } while (!flux_rpc_check (thenbug_r)); ok (true, "thenbug: check says message ready"); ok (flux_rpc_then (thenbug_r, then_cb, h) == 0, "thenbug: registered then - hangs on failure"); ok (flux_reactor_start (h) == 0, "reactor completed normally"); flux_rpc_destroy (thenbug_r); flux_msg_watcher_delvec (h, htab); flux_close (h); done_testing(); return (0); }
void rpctest_begin_cb (flux_t *h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { const char *json_str; flux_rpc_t *r; errno = 0; ok (!(r = flux_rpc (h, NULL, NULL, FLUX_NODEID_ANY, 0)) && errno == EINVAL, "flux_rpc with NULL topic fails with EINVAL"); /* working no-payload RPC */ ok ((r = flux_rpc (h, "rpctest.hello", NULL, FLUX_NODEID_ANY, 0)) != NULL, "flux_rpc with no payload when none is expected works"); ok (flux_rpc_check (r) == false, "flux_rpc_check says get would block"); ok (flux_rpc_get (r, NULL) == 0, "flux_rpc_get works"); flux_rpc_destroy (r); /* cause remote EPROTO (unexpected payload) - will be picked up in _get() */ ok ((r = flux_rpc (h, "rpctest.hello", "{}", FLUX_NODEID_ANY, 0)) != NULL, "flux_rpc with payload when none is expected works, at first"); ok (flux_rpc_check (r) == false, "flux_rpc_check says get would block"); errno = 0; ok (flux_rpc_get (r, NULL) < 0 && errno == EPROTO, "flux_rpc_get fails with EPROTO"); flux_rpc_destroy (r); /* cause remote EPROTO (missing payload) - will be picked up in _get() */ errno = 0; ok ((r = flux_rpc (h, "rpctest.echo", NULL, FLUX_NODEID_ANY, 0)) != NULL, "flux_rpc with no payload when payload is expected works, at first"); ok (flux_rpc_check (r) == false, "flux_rpc_check says get would block"); errno = 0; ok (flux_rpc_get (r, NULL) < 0 && errno == EPROTO, "flux_rpc_get fails with EPROTO"); flux_rpc_destroy (r); /* working with-payload RPC */ ok ((r = flux_rpc (h, "rpctest.echo", "{}", FLUX_NODEID_ANY, 0)) != NULL, "flux_rpc with payload when payload is expected works"); ok (flux_rpc_check (r) == false, "flux_rpc_check says get would block"); json_str = NULL; ok (flux_rpc_get (r, &json_str) == 0 && json_str && !strcmp (json_str, "{}"), "flux_rpc_get works and returned expected payload"); flux_rpc_destroy (r); /* working with-payload RPC (raw) */ char *d, data[] = "aaaaaaaaaaaaaaaaaaaa"; int l, len = strlen (data); ok ((r = flux_rpc_raw (h, "rpctest.rawecho", data, len, FLUX_NODEID_ANY, 0)) != NULL, "flux_rpc_raw with payload when payload is expected works"); ok (flux_rpc_check (r) == false, "flux_rpc_check says get would block"); json_str = NULL; ok (flux_rpc_get_raw (r, &d, &l) == 0 && d != NULL && l == len && memcmp (data, d, len) == 0, "flux_rpc_get_raw works and returned expected payload"); flux_rpc_destroy (r); /* use newish pack/unpack payload interfaces */ int i = 0; ok ((r = flux_rpcf (h, "rpctest.incr", FLUX_NODEID_ANY, 0, "{s:i}", "n", 107)) != NULL, "flux_rpcf works"); ok (flux_rpc_getf (r, "{s:i}", "n", &i) == 0, "flux_rpc_getf works"); ok (i == 108, "and service returned incremented value"); flux_rpc_destroy (r); flux_reactor_stop (flux_get_reactor (h)); }
static flux_msg_t *op_recv (void *impl, int flags) { ctx_t *ctx = impl; assert (ctx->magic == MODHANDLE_MAGIC); zmq_pollitem_t zp = { .events = ZMQ_POLLIN, .socket = ctx->sock, .revents = 0, .fd = -1, }; flux_msg_t *msg = NULL; if (connect_socket (ctx) < 0) goto done; if ((flags & FLUX_O_NONBLOCK)) { int n; if ((n = zmq_poll (&zp, 1, 0L)) <= 0) { if (n == 0) errno = EWOULDBLOCK; goto done; } } msg = flux_msg_recvzsock (ctx->sock); done: return msg; } static int op_event_subscribe (void *impl, const char *topic) { ctx_t *ctx = impl; assert (ctx->magic == MODHANDLE_MAGIC); json_object *in = Jnew (); flux_rpc_t *rpc = NULL; int rc = -1; if (connect_socket (ctx) < 0) goto done; Jadd_str (in, "topic", topic); if (!(rpc = flux_rpc (ctx->h, "cmb.sub", Jtostr (in), FLUX_NODEID_ANY, 0)) || flux_rpc_get (rpc, NULL) < 0) goto done; rc = 0; done: Jput (in); flux_rpc_destroy (rpc); return rc; }