updateRequest(*req, job);
if (!prepareJobNeeded(job, *req, status)) {
if (status != Job::done) {
- job.state = FaxRequest::state_done;
+ job.state = FaxRequest::state_failed;
deleteRequest(job, req, status, true);
setDead(job);
} else
* notified of the requeue as well as the timeout?
*/
fxAssert(!job.suspendPending, "Interrupted job timed out");
- job.state = FaxRequest::state_done;
+ job.state = FaxRequest::state_failed;
deleteRequest(job, req, Job::timedout, true);
setDead(job);
} else if (req->status == send_retry) {
job.suspendPending = false;
delete req; // implicit unlock of q file
} else {
- job.state = FaxRequest::state_done;
- traceQueue(job, "SEND DONE: " | strTime(duration));
- Trigger::post(Trigger::SEND_DONE, job);
// NB: always notify client if job failed
- if (req->status == send_failed)
+ if (req->status == send_failed) {
+ job.state = FaxRequest::state_failed;
deleteRequest(job, req, Job::failed, true, fmtTime(duration));
- else
+ } else {
+ job.state = FaxRequest::state_done;
deleteRequest(job, req, Job::done, false, fmtTime(duration));
+ }
+ traceQueue(job, "SEND DONE: " | strTime(duration));
+ Trigger::post(Trigger::SEND_DONE, job);
setDead(job);
}
}
void
faxQueueApp::setDead(Job& job)
{
- job.state = FaxRequest::state_done;
+ if (job.state != FaxRequest::state_done
+ && job.state != FaxRequest::state_failed)
+ job.state = FaxRequest::state_failed;
job.suspendPending = false;
traceJob(job, "DEAD");
Trigger::post(Trigger::JOB_DEAD, job);
setSuspend(job);
return (true);
case FaxRequest::state_done:
+ case FaxRequest::state_failed:
setDead(job);
return (true);
}
* Recheck the job state; it may have changed while
* we were waiting for the subprocess to terminate.
*/
- if (job.state != FaxRequest::state_done)
+ if (job.state != FaxRequest::state_done &&
+ job.state != FaxRequest::state_failed)
break;
/* fall thru... */
case FaxRequest::state_done:
+ case FaxRequest::state_failed:
return (false);
case FaxRequest::state_sleeping:
case FaxRequest::state_pending:
{
Job* job = Job::getJobByID(jobid);
if (job && suspendJob(*job, true)) {
- job->state = FaxRequest::state_done;
+ job->state = FaxRequest::state_failed;
Trigger::post(Trigger::JOB_KILL, *job);
FaxRequest* req = readRequest(*job);
if (req)
req.status = send_failed;
req.notice = reason;
traceServer("JOB " | job.jobid | ": " | reason);
- job.state = FaxRequest::state_done;
+ job.state = FaxRequest::state_failed;
Trigger::post(Trigger::JOB_REJECT, job);
setDead(job); // dispose of job
}
Trigger::post(Trigger::JOB_TIMEDOUT, job);
if (job.state != FaxRequest::state_active) {
job.remove(); // remove from sleep queue
- job.state = FaxRequest::state_done;
+ job.state = FaxRequest::state_failed;
FaxRequest* req = readRequest(job);
if (req)
deleteRequest(job, req, Job::timedout, true);
void
faxQueueApp::timeoutJob(Job& job, FaxRequest& req)
{
- job.state = FaxRequest::state_done;
+ job.state = FaxRequest::state_failed;
traceQueue(job, "KILL TIME EXPIRED");
Trigger::post(Trigger::JOB_TIMEDOUT, job);
deleteRequest(job, req, Job::timedout, true);
delete req; // NB: unlock qfile
} else
setDead(*job); // XXX???
- } else if (job->state == FaxRequest::state_done)
+ } else if (job->state == FaxRequest::state_done ||
+ job->state == FaxRequest::state_failed)
jobError(*job, "Cannot resubmit a completed job");
else
ok = true; // other, nothing to do
*/
bool reject;
if (req.readQFile(reject) && !reject &&
- req.state != FaxRequest::state_done) {
+ req.state != FaxRequest::state_done &&
+ req.state != FaxRequest::state_failed) {
status = submitJob(req, checkState);
} else if (reject) {
Job job(req);
- job.state = FaxRequest::state_done;
+ job.state = FaxRequest::state_failed;
req.status = send_failed;
req.notice = "Invalid or corrupted job description file";
traceServer("JOB " | jobid | ": " | req.notice);
// NB: this may not work, but we try...
deleteRequest(job, req, Job::rejected, true);
- } else if (req.state == FaxRequest::state_done) {
+ } else if (req.state == FaxRequest::state_done ||
+ req.state == FaxRequest::state_failed) {
logError("JOB %s: Cannot resubmit a completed job",
(const char*) jobid);
} else
}
req.qfile = dest; // moved to doneq
job.file = req.qfile; // ...and track change
- req.state = FaxRequest::state_done; // job is definitely done
+ if (why == Job::done)
+ req.state = FaxRequest::state_done; // job is definitely done
+ else
+ req.state = FaxRequest::state_failed;// job is definitely done
req.pri = job.pri; // just in case someone cares
req.tts = Sys::now(); // mark job termination time
req.writeQFile();
{
static const char* stateNames[] = {
"state#0", "suspended", "pending", "sleeping", "blocked",
- "ready", "active", "done"
+ "ready", "active", "done", "failed"
};
time_t now = Sys::now();
vlogInfo(
"JOB " | job.jobid
- | " (" | stateNames[job.state&7]
+ | " (" | stateNames[job.state%9]
| " dest " | job.dest
| fxStr::format(" pri %u", job.pri)
| " tts " | strTime(job.tts - now)
Job* job = preJobCmd("delete", jobid, emsg);
if (job) {
if (job->state != FaxRequest::state_done &&
+ job->state != FaxRequest::state_failed &&
job->state != FaxRequest::state_suspended) {
reply(504, "Job %s not deleted; use JSUSP first.", jobid);
return;
fxStr emsg;
Job* job = preJobCmd(what, jobid, emsg);
if (job) {
- if (job->state == FaxRequest::state_done) {
+ if (job->state == FaxRequest::state_done ||
+ job->state == FaxRequest::state_failed) {
reply(504, "Job %s not %sed; already done.", jobid, what);
return;
}
fxStr emsg;
Job* job = preJobCmd("submit", jobid, emsg);
if (job) {
- if (job->state == FaxRequest::state_done) {
+ if (job->state == FaxRequest::state_done ||
+ job->state == FaxRequest::state_failed) {
reply(504, "Job %s not submitted; already done.", jobid);
return;
}
reply(504, "Cannot wait for default job.");
return;
}
- if (job->state == FaxRequest::state_done) {
+ if (job->state == FaxRequest::state_done ||
+ job->state == FaxRequest::state_failed) {
reply(216, "Job %s done (already).", jobid);
return;
}
* blindly hold a reference to the in-memory structure.
*/
job = findJob(jobid, emsg);
- if (!job || job->state == FaxRequest::state_done)
+ if (!job || job->state == FaxRequest::state_done ||
+ job->state == FaxRequest::state_failed)
break;
}
reply(216, "Wait for job %s completed.", jobid);
break;
#endif /* OLDPROTO_SUPPORT */
case 'a':
- fprintf(fd, fspec, "?TPSBWRD"[job.state]);
+ fprintf(fd, fspec, "?TPSBWRDF"[job.state]);
break;
case 'b':
fprintf(fd, fspec, job.ntries);