af::Msg * JobContainer::registerJob( JSON & i_object, UserContainer * i_users, MonitorContainer * i_monitoring) { JobAf * job = new JobAf( i_object); int32_t id = 0; int64_t serial = 0; std::string err; if( registerJob( job, err, i_users, i_monitoring)) { id = job->getId(); serial = job->getSerial(); } else job = NULL; std::ostringstream oss; oss << "{"; oss << "\n\"id\":" << id; oss << ",\n\"serial\":" << serial; if( err.size()) { oss << ",\n\"error\":\"" << err << "\""; } else if( job == NULL ) { oss << ",\n\"error\":\"Job registration failed. See server log for details.\""; } oss << "\n}"; return af::jsonMsg( oss); }
/* ACKJOB jobid_1 jobid_2 ... jobid_N * * Set job state as acknowledged, if the job does not exist creates a * fake job just to hold the acknowledge. * * As a result of a job being acknowledged, the system tries to garbage * collect it, that is, to remove the job from every node of the system * in order to both avoid multiple deliveries of the same job, and to * release resources. * * If a job was already acknowledged, the ACKJOB command still has the * effect of forcing a GC attempt ASAP. * * The command returns the number of jobs already known and that were * already not in the ACKED state. */ void ackjobCommand(client *c) { int j, known = 0; if (validateJobIDs(c,c->argv+1,c->argc-1) == C_ERR) return; /* Perform the appropriate action for each job. */ for (j = 1; j < c->argc; j++) { job *job = lookupJob(c->argv[j]->ptr); /* Case 1: No such job. Create one just to hold the ACK. However * if the cluster is composed by a single node we are sure the job * does not exist in the whole cluster, so do this only if the * cluster size is greater than one. */ if (job == NULL && server.cluster->size > 1 && !myselfLeaving()) { char *id = c->argv[j]->ptr; int ttl = getRawTTLFromJobID(id); /* TTL is even for "at most once" jobs. In this case we * don't need to create a dummy hack. */ if (ttl & 1) { job = createJob(id,JOB_STATE_ACKED,0,0); setJobTTLFromID(job); serverAssert(registerJob(job) == C_OK); } } /* Case 2: Job exists and is not acknowledged. Change state. */ else if (job && job->state != JOB_STATE_ACKED) { dequeueJob(job); /* Safe to call if job is not queued. */ acknowledgeJob(job); known++; } /* Anyway... start a GC attempt on the acked job. */ if (job) tryJobGC(job); } addReplyLongLong(c,known); }