DUE TO SPAM, SIGN-UP IS DISABLED. Goto Selfserve wiki signup and request an account.

DUE TO SPAM, SIGN-UP IS DISABLED. Goto Selfserve wiki signup and request an account.
...
Follow code snaplet gives a synchronized synchronous handling logic example that is supported in the new model.
| Code Block |
|---|
@Override
public <T extends VMInstanceVO> boolean advanceStop(final T vm, boolean forced, User user, Account account) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
VmWorkJobVO workJob = null;
Transaction txn = Transaction.currentTxn();
try {
txn.start();
_vmDao.lockRow(vm.getId(), true);
List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
VirtualMachine.Type.Instance, vm.getId(), VmWorkConstants.VM_WORK_STOP);
if(pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
assert(pendingWorkJobs.size() == 1);
workJob = pendingWorkJobs.get(0);
} else {
workJob = new VmWorkJobVO();
workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
workJob.setCmd(VmWorkConstants.VM_WORK_STOP);
workJob.setAccountId(account.getId());
workJob.setUserId(user.getId());
workJob.setStep(VmWorkJobVO.Step.Prepare);
workJob.setVmType(vm.getType());
workJob.setVmInstanceId(vm.getId());
// save work context info (there are some duplications)
VmWorkStop workInfo = new VmWorkStop();
workInfo.setAccountId(account.getId());
workInfo.setUserId(user.getId());
workInfo.setVmId(vm.getId());
workInfo.setForceStop(forced);
workJob.setCmdInfo(ApiSerializerHelper.toSerializedString(workInfo));
_jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
}
txn.commit();
} catch(Throwable e) {
s_logger.error("Unexpected exception", e);
txn.rollback();
throw new ConcurrentOperationException("Unhandled exception, converted to ConcurrentOperationException");
}
final long jobId = workJob.getId();
AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
//
// TODO : this will be replaced with fully-asynchronizedasynchronous way later so that we don't need
// to wait here. The reason we do it synchronizedsynchronous here is that callers of advanceStart is expecting
// synchronizedsynchronous semantics
//
//
_jobMgr.waitAndCheck(
new String[] { TopicConstants.VM_POWER_STATE, TopicConstants.JOB_STATE },
3000L, 600000L, new Predicate() {
@Override
public boolean checkCondition() {
VMInstanceVO instance = _vmDao.findById(vm.getId());
if(instance.getPowerState() == VirtualMachine.PowerState.PowerOff)
return true;
VmWorkJobVO workJob = _workJobDao.findById(jobId);
if(workJob.getStatus() != AsyncJobConstants.STATUS_IN_PROGRESS)
return true;
return false;
}
});
try {
AsyncJobExecutionContext.getCurrentExecutionContext().disjoinJob(jobId);
} catch(Exception e) {
s_logger.error("Unexpected exception", e);
return false;
}
return true;
}
|
...
A job in CloudStack actually represents an orchestration work flow. Due to historic reason, CloudStack has taken considerable efforts trying to make the concept of job implicit to programmers, this is done through the API Command pattern, for API command that is executed asynchronizedlyasynchronously, the request will first be posted to an internal job facility but real execution/processing will be called back into the command object from within the job thread context. The whole job facility has been made implicit intentionally, in most of cases, job facility is used as a context switcher to just provide the execution thread context. This implicit use of job facility actually treats job as secondary class, since explicit job control is discouraged, it leads to the programming model to handle things in-place within the calling context, synchronization is then usually done through locking.
In this refactoring proposal, we will promote jobs into first-class objects, jobs are encouraged to be used in a more explicit way. We will use ordered orderly execution to help reduce the use of locking across the code base and manage orchestration processes explicitly. This will give us better control on managing system load.
...
API job gives a running context for an asynchronized asynchronous API request, it usually starts an orchestration process.
...
Inside CloudStack, there are a few manager components that use their own threads to manage service activities, when it comes to use the newly introduced work jobs for orchestration, we sometimes need a pseudo job context, pseudo job provides just that context. The difference between Pseudo job and an high level API job is that pseudo job runs in its own thread context, while API job runs in the thread from job thread pool.
...