static int job_status_cb (const char *jcbstr, void *arg, int errnum) { int64_t os = 0; int64_t ns = 0; int64_t j = 0; jstatctx_t *ctx = NULL; flux_t h = (flux_t)arg; JSON jcb = NULL; ctx = getctx (h); if (errnum > 0) { flux_log (ctx->h, LOG_ERR, "job_status_cb: errnum passed in"); return -1; } if (!(jcb = Jfromstr (jcbstr))) { flux_log (ctx->h, LOG_ERR, "job_status_cb: error parsing JSON string"); return -1; } get_jobid (jcb, &j); get_states (jcb, &os, &ns); Jput (jcb); fprintf (ctx->op, "%s->%s\n", jsc_job_num2state ((job_state_t)os), jsc_job_num2state ((job_state_t)ns)); fflush (ctx->op); return 0; }
static int send_state_event (flux_t *h, job_state_t st, int64_t j) { flux_msg_t *msg; char *json = NULL; char *topic = NULL; int rc = -1; if (asprintf (&topic, "jsc.state.%s", jsc_job_num2state (st)) < 0) { errno = ENOMEM; flux_log_error (h, "create state change event: %s", jsc_job_num2state (st)); goto done; } if ((msg = flux_event_pack (topic, "{ s:I }", "lwj", j)) == NULL) { flux_log_error (h, "flux_event_pack"); goto done; } if (flux_send (h, msg, 0) < 0) flux_log_error (h, "flux_send event"); flux_msg_destroy (msg); rc = 0; done: free (topic); free (json); return rc; }
static bool job_is_finished (const char *state) { if (strcmp (state, jsc_job_num2state (J_COMPLETE)) == 0 || strcmp (state, jsc_job_num2state (J_FAILED)) == 0) return true; return false; }
static int update_state (flux_t h, int64_t j, JSON o) { int rc = -1; int64_t st = 0; char *key; if (!Jget_int64 (o, JSC_STATE_PAIR_NSTATE, &st)) return -1; if ((st >= J_FOR_RENT) || (st < J_NULL)) return -1; key = xasprintf ("lwj.%"PRId64".state", j); if (kvs_put_string (h, key, jsc_job_num2state ((job_state_t)st)) < 0) flux_log_error (h, "update %s", key); else if (kvs_commit (h) < 0) flux_log_error (h, "commit %s", key); else { flux_log (h, LOG_DEBUG, "job (%"PRId64") assigned new state: %s", j, jsc_job_num2state ((job_state_t)st)); rc = 0; } free (key); if (send_state_event (h, st, j) < 0) flux_log_error (h, "send state event"); 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; }
static int update_state (flux_t *h, int64_t j, json_object *o) { int rc = -1; int64_t st = 0; char *key = NULL; flux_kvs_txn_t *txn = NULL; flux_future_t *f = NULL; if (!Jget_int64 (o, JSC_STATE_PAIR_NSTATE, &st)) goto done; if ((st >= J_FOR_RENT) || (st < J_NULL)) goto done; if (!(key = lwj_key (h, j, ".state"))) goto done; if (!(txn = flux_kvs_txn_create ())) { flux_log_error (h, "txn_create"); goto done; } if (flux_kvs_txn_pack (txn, 0, key, "s", jsc_job_num2state ((job_state_t)st)) < 0) { flux_log_error (h, "update %s", key); goto done; } if (!(f = flux_kvs_commit (h, 0, txn)) || flux_future_get (f, NULL) < 0) { flux_log_error (h, "commit %s", key); goto done; } flux_log (h, LOG_DEBUG, "job (%"PRId64") assigned new state: %s", j, jsc_job_num2state ((job_state_t)st)); rc = 0; if (send_state_event (h, st, j) < 0) flux_log_error (h, "send state event"); done: flux_future_destroy (f); flux_kvs_txn_destroy (txn); free (key); return rc; }
static int update_state (flux_t h, int64_t j, JSON o) { int rc = -1; int64_t st = 0; char key[20] = {'\0'}; if (!Jget_int64 (o, JSC_STATE_PAIR_NSTATE, &st)) return -1; if ((st >= J_FOR_RENT) || (st < J_NULL)) return -1; snprintf (key, 20, "lwj.%ld.state", j); if (kvs_put_string (h, key, jsc_job_num2state ((job_state_t)st)) < 0) flux_log (h, LOG_ERR, "update %s: %s", key, strerror (errno)); else if (kvs_commit (h) < 0) flux_log (h, LOG_ERR, "commit %s: %s", key, strerror (errno)); else { flux_log (h, LOG_DEBUG, "job (%ld) assigned new state: %s", j, jsc_job_num2state ((job_state_t)st)); rc = 0; } return rc; }
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 bool complete_job (wjctx_t *ctx) { JSON jcb = NULL; JSON o = NULL; bool rc = false; char *json_str = NULL; int64_t state = J_NULL; if (jsc_query_jcb (ctx->h, ctx->jobid, JSC_STATE_PAIR, &json_str) == 0) { jcb = Jfromstr (json_str); Jget_obj (jcb, JSC_STATE_PAIR, &o); Jget_int64 (o, JSC_STATE_PAIR_NSTATE, &state); Jput (jcb); free (json_str); flux_log (ctx->h, LOG_INFO, "%"PRId64" already started (%s)", ctx->jobid, jsc_job_num2state (state)); if (state == J_COMPLETE) { flux_log (ctx->h, LOG_INFO, "%"PRId64" already completed", ctx->jobid); rc = true; } } return rc; }