@SuppressWarnings("rawtypes") @Override protected Collection acquireJobs() { Collection jobs = Collections.EMPTY_LIST; if ((isActive) && (!alfrescoJobExecutor.getTransactionService().isReadOnly())) { try { jobs = alfrescoJobExecutor .getTransactionService() .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionHelper.RetryingTransactionCallback<Collection>() { public Collection execute() throws Throwable { if (jobLockToken != null) { refreshExecutorLock(jobLockToken); } else { jobLockToken = getExecutorLock(); } try { return AlfrescoJobExecutorThread.super.acquireJobs(); } catch (Throwable t) { logger.error("Failed to acquire jobs"); releaseExecutorLock(jobLockToken); jobLockToken = null; throw t; } } }); if (jobs != null) { if (logger.isDebugEnabled() && (!logger.isTraceEnabled()) && (!jobs.isEmpty())) { logger.debug("acquired " + jobs.size() + " job" + ((jobs.size() != 1) ? "s" : "")); } if (logger.isTraceEnabled()) { logger.trace( "acquired " + jobs.size() + " job" + ((jobs.size() != 1) ? "s" : "") + ((jobs.size() > 0) ? ": " + jobs.toString() : "")); } if (jobs.size() == 0) { releaseExecutorLock(jobLockToken); jobLockToken = null; } } } catch (LockAcquisitionException e) { // ignore jobLockToken = null; } } return jobs; }
private String getExecutorLock() { String lockToken = null; if (alfrescoJobExecutor.getJobExecutorLockEnabled()) { try { lockToken = alfrescoJobExecutor.getJobLockService().getLock(LOCK_QNAME, jobLockTTL, 3000, 10); if (logger.isTraceEnabled()) { logger.trace(Thread.currentThread().getName() + " got lock token: " + lockToken); } } catch (LockAcquisitionException e) { if (logger.isTraceEnabled()) { logger.trace( "Failed to get Alfresco Job Executor lock - may already running in another thread"); } throw e; } } return lockToken; }
@Override protected Date getNextDueDate() { if (!isActive) { return null; } return alfrescoJobExecutor .getTransactionService() .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionHelper.RetryingTransactionCallback<Date>() { public Date execute() throws Throwable { return AlfrescoJobExecutorThread.super.getNextDueDate(); } }, true); }
private void releaseExecutorLock(String lockToken) { if (lockToken != null) { try { alfrescoJobExecutor.getJobLockService().releaseLock(lockToken, LOCK_QNAME); if (logger.isTraceEnabled()) { logger.trace(Thread.currentThread().getName() + " released lock token: " + lockToken); } } catch (LockAcquisitionException e) { if (logger.isTraceEnabled()) { logger.trace( "Failed to release Alfresco Job Executor lock - may no longer exist (" + lockToken + ")"); } throw e; } } }
/** {@inheritDoc} */ @Override protected void executeJob(final Job jobIn) { if ((!isActive) || (alfrescoJobExecutor.getTransactionService().isReadOnly())) { return; } // based on JBPM 3.3.1 (JobExecutorThread.executeJob) // - wrap executeJob / deleteJob in Alfresco retries // - add setRollbackOnly warnings // - if Alfresco retries fail, attempt to set JBPM job exception/retries try { RetryingTransactionHelper tranHelper = alfrescoJobExecutor.getTransactionService().getRetryingTransactionHelper(); tranHelper.doInTransaction( new RetryingTransactionCallback<Object>() { public Object execute() throws Throwable { JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext(); try { JobSession jobSession = jbpmContext.getJobSession(); Job job = jobSession.loadJob(jobIn.getId()); if (logger.isTraceEnabled()) { logger.trace("executing " + job); } if (job.execute(jbpmContext)) { jobSession.deleteJob(job); if (logger.isDebugEnabled()) { logger.debug("executed and deleted: " + job); } } // if this job is locked too long long totalLockTimeInMillis = System.currentTimeMillis() - job.getLockTime().getTime(); if (totalLockTimeInMillis > jbpmMaxLockTime) { logger.warn( "setRollbackOnly: exceeded maxLockTime (" + jbpmMaxLockTime + ") " + job); jbpmContext.setRollbackOnly(); } } finally { jbpmContext.close(); } return null; } }); } catch (LockAcquisitionException e) { // ignore jobLockToken = null; } catch (Exception e) { if (logger.isErrorEnabled()) { logger.error("failed to execute " + jobIn, e); } if (!isPersistenceException(e)) { try { final StringWriter memoryWriter = new StringWriter(); e.printStackTrace(new PrintWriter(memoryWriter)); RetryingTransactionHelper tranHelper = alfrescoJobExecutor.getTransactionService().getRetryingTransactionHelper(); tranHelper.doInTransaction( new RetryingTransactionCallback<Object>() { public Object execute() throws Throwable { JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext(); try { JobSession jobSession = jbpmContext.getJobSession(); final Job job = jobSession.loadJob(jobIn.getId()); if (logger.isDebugEnabled()) { logger.debug("attempting to update exception/retries: " + job); } job.setException(memoryWriter.toString()); job.setRetries(job.getRetries() - 1); if (logger.isInfoEnabled()) { logger.info( "updated job exception and set to " + job.getRetries() + " retries: " + jobIn); } } finally { jbpmContext.close(); } return null; } }); } catch (Exception e2) { if (logger.isErrorEnabled()) { logger.error("failed to update job exception/retries " + jobIn, e2); } } } } }