@PUT @Path("job/{id}.xml") @Produces(MediaType.TEXT_XML) @RestQuery(name = "updatejob", description = "Updates an existing job", returnDescription = "No content", pathParameters = { @RestParameter(name = "id", isRequired = true, type = Type.STRING, description = "The job identifier") }, restParameters = { @RestParameter(name = "job", isRequired = true, type = Type.TEXT, description = "The updated job as XML") }, reponses = { @RestResponse(responseCode = SC_NO_CONTENT, description = "Job updated."), @RestResponse(responseCode = SC_NOT_FOUND, description = "Job not found.") }) public Response updateJob(@PathParam("id") String id, @FormParam("job") String jobXml) throws NotFoundException { try { Job job = JobParser.parseJob(jobXml); serviceRegistry.updateJob(job); return Response.status(Status.NO_CONTENT).build(); } catch (Exception e) { throw new WebApplicationException(e); } }
/** * {@inheritDoc} * * @see org.opencastproject.job.api.JobProducer#acceptJob(org.opencastproject.job.api.Job) */ @Override public void acceptJob(final Job job) throws ServiceRegistryException { final Job runningJob; try { job.setStatus(Job.Status.RUNNING); runningJob = getServiceRegistry().updateJob(job); } catch (NotFoundException e) { throw new IllegalStateException(e); } executor.submit(new JobRunner(runningJob, getServiceRegistry().getCurrentJob())); }
private void handleFailedProcessing(final Throwable t) throws Exception { if (t instanceof JobCanceledException) { logger.info(t.getMessage()); } else { Job jobAfterProcessing = getServiceRegistry().getJob(jobId); jobAfterProcessing.setStatus(Status.FAILED); jobAfterProcessing = getServiceRegistry().updateJob(jobAfterProcessing); getServiceRegistry().incident().unhandledException(jobAfterProcessing, Severity.FAILURE, t); logger.error("Error handling operation '{}': {}", jobAfterProcessing.getOperation(), getStackTrace(t)); if (t instanceof ServiceRegistryException) throw (ServiceRegistryException) t; } }
/** * Private utility to update and optionally fail job, called from a finally block. * * @param job * to be updated, may be null */ protected void finallyUpdateJob(Job job) { if (job == null) { return; } if (!Job.Status.FINISHED.equals(job.getStatus())) { job.setStatus(Job.Status.FAILED); } try { getServiceRegistry().updateJob(job); } catch (Exception e) { throw new RuntimeException(e); } }
private void wakeWaiterJob() { if (this.waiterJobId.isSome()) { try { final Job waiter = serviceRegistry.getJob(waiterJobId.get()); waiter.setStatus(Job.Status.RUNNING); for (Job j : jobs) { Job updatedJob = this.serviceRegistry.getJob(j.getId()); updatedJob.removeBlockingJobId(); // FYI not updating local j in jobs collection this.serviceRegistry.updateJob(updatedJob); } waiter.removeBlockedJobsIds(); this.serviceRegistry.updateJob(waiter); } catch (ServiceRegistryException e) { logger.warn("Unable to put {} into a waiting state, this may cause a deadlock: {}", waiterJobId, e.getMessage()); } catch (NotFoundException e) { logger.warn("Unable to put {} into a waiting state, job not found by the service registry. This may cause a deadlock: {}", waiterJobId, e.getMessage()); } } else { logger.debug("No waiting job set, unable to put waiting job into waiting state"); } }
private void handleSuccessfulProcessing(final String payload) throws Exception { // The job may gets updated internally during processing. It therefore needs to be reload from the service // registry in order to prevent inconsistencies. final Job jobAfterProcessing = getServiceRegistry().getJob(jobId); jobAfterProcessing.setPayload(payload); jobAfterProcessing.setStatus(Status.FINISHED); getServiceRegistry().updateJob(jobAfterProcessing); }
private void suspendWaiterJob() { if (this.waiterJobId.isSome()) { try { final Job waiter = serviceRegistry.getJob(waiterJobId.get()); waiter.setStatus(Job.Status.WAITING); List<Long> blockedForJobs = new LinkedList<Long>(); for (Job j : jobs) { try { if (setBlockerJob(j, waiter)) { blockedForJobs.add(j.getId()); } } catch (OptimisticLockException e) { // Try again, this happens if the job finishes before we get here // If the same exception happens again then we're in a very weird state if (setBlockerJob(j, waiter)) { blockedForJobs.add(j.getId()); } } } waiter.setBlockedJobIds(blockedForJobs); this.serviceRegistry.updateJob(waiter); } catch (ServiceRegistryException e) { logger.warn("Unable to put {} into a waiting state, this may cause a deadlock: {}", waiterJobId, e.getMessage()); } catch (NotFoundException e) { logger.warn("Unable to put {} into a waiting state, job not found by the service registry. This may cause a deadlock: {}", waiterJobId, e.getMessage()); } } else { logger.debug("No waiting job set, unable to put waiting job into waiting state"); } }
/** * Sets j's blocking job ID (ie, the job which it is blocking) to waiter's ID * @param j * The job doing the blocking * @param waiter * The job blocking, waiting for its child to finish * @return * True if j is an active job and has been successfully updated, false if it is not an active job * @throws ServiceRegistryException * @throws NotFoundException */ private boolean setBlockerJob(Job j, Job waiter) throws ServiceRegistryException, NotFoundException { Job blockerJob = this.serviceRegistry.getJob(j.getId()); if (j.getStatus().isActive()) { blockerJob.setBlockingJobId(waiter.getId()); // FYI not updating local j in jobs collection this.serviceRegistry.updateJob(blockerJob); return true; } else { return false; } }