int shutdown_decode (const flux_msg_t *msg, double *grace, int *exitcode, int *rank, char *reason, int reason_len) { const char *json_str, *s; JSON in = NULL; int rc = -1; if (flux_event_decode (msg, NULL, &json_str) < 0 || !(in = Jfromstr (json_str)) || !Jget_str (in, "reason", &s) || !Jget_double (in, "grace", grace) || !Jget_int (in, "rank", rank) || !Jget_int (in, "exitcode", exitcode)) { errno = EPROTO; goto done; } snprintf (reason, reason_len, "%s", s); rc = 0; done: Jput (in); return rc; }
/* 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; }
/* Accept a json payload, verify it and return error if it doesn't * match expected. */ void sink_request_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { const char *json_str; int saved_errno; JSON o = NULL; double d; int rc = -1; if (flux_request_decode (msg, NULL, &json_str) < 0) { saved_errno = errno; goto done; } if (!(o = Jfromstr (json_str)) || !Jget_double (o, "pi", &d) || d != 3.14) { saved_errno = errno = EPROTO; goto done; } rc = 0; done: if (flux_respond (h, msg, rc < 0 ? saved_errno : 0, NULL) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); Jput (o); }
// Recevied a request to join the simulation ("sim.join") static void join_cb (flux_t *h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { int mod_rank; json_t *request = NULL; const char *mod_name = NULL, *json_str = NULL; double *next_event = (double *)malloc (sizeof (double)); ctx_t *ctx = arg; sim_state_t *sim_state = ctx->sim_state; uint32_t size; if (flux_msg_get_json (msg, &json_str) < 0 || json_str == NULL || !(request = Jfromstr (json_str)) || !Jget_str (request, "mod_name", &mod_name) || !Jget_int (request, "rank", &mod_rank) || !Jget_double (request, "next_event", next_event)) { flux_log (h, LOG_ERR, "%s: bad join message", __FUNCTION__); goto out; } if (flux_get_size (h, &size) < 0) goto out; if (mod_rank < 0 || mod_rank >= size) { flux_log (h, LOG_ERR, "%s: bad rank in join message", __FUNCTION__); goto out; } flux_log (h, LOG_DEBUG, "join rcvd from module %s on rank %d, next event at %f", mod_name, mod_rank, *next_event); zhash_t *timers = sim_state->timers; if (zhash_insert (timers, mod_name, next_event) < 0) { // key already // exists flux_log (h, LOG_ERR, "duplicate join request from %s, module already exists in " "sim_state", mod_name); goto out; } // clear next event so it is not freed below next_event = NULL; // TODO: this is horribly hackish, improve the handshake to avoid // this hardcoded # of modules. maybe use a timeout? ZMQ provides // support for polling etc with timeouts, should try that static int num_modules = 3; num_modules--; if (num_modules <= 0) { if (handle_next_event (ctx) < 0) { flux_log (h, LOG_ERR, "failure while handling next event"); return; } } out: Jput (request); free (next_event); }