Details
-
New Feature
-
Resolution: Unresolved
-
Major - P3
-
None
-
None
-
Service Arch
Description
ControllableJob provides the following APIs to allow periodically running a background job:
/**
|
class ControllableJob { |
public: |
// Starts running the job. |
virtual void start() = 0; |
|
|
// Pauses the job temporarily so that it does not execute until unpaused. |
virtual void pause() = 0; |
|
|
// Resumes a paused job so that it continues executing each interval. |
virtual void resume() = 0; |
|
|
// Stops the job, this function blocks until the job is stopped. |
virtual void stop() = 0; |
};
|
This API could be extended to support waking background jobs:
class ControllableJob { |
public: |
...
|
/* |
* Notifies the job to run so long as it's not paused or cancelled.
|
* The job should stop (or skip) waiting and run as soon as possible.
|
* Returns `false` if the job is already paused or cancelled, and `true` otherwise.
|
*/
|
virtual bool wakeUp() = 0; |
...
|
};
|
A possible implementation for PeriodicJobImpl could be based on a bool member that records wakeUp attempts:
bool PeriodicRunnerImpl::PeriodicJobImpl::wakeUp() { |
{
|
stdx::lock_guard lk(_mutex);
|
if (_execStatus != ExecutionStatus::RUNNING) |
return false; |
_notified = true; |
}
|
_condvar.notify_one();
|
return true; |
}
|
...
|
void PeriodicRunnerImpl::PeriodicJobImpl::_run() { |
...
|
do { |
auto deadline = getDeadlineFromInterval();
|
if (_clockSource->waitForConditionUntil(_condvar, lk, deadline, [&] { |
return _notified || _execStatus == ExecutionStatus::CANCELED || getDeadlineFromInterval() != deadline; |
})) {
|
if (_execStatus == ExecutionStatus::CANCELED) { |
return; |
}
|
if (std::exchange(_notified, false)) { |
break; |
}
|
}
|
} while (_clockSource->now() < getDeadlineFromInterval()); |
...
|
}
|