Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-73548

Extend `ControllableJob` to support waking background jobs

    • Type: Icon: New Feature New Feature
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: Internal Code
    • Labels:
    • Service Arch

      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());
          ...
      }
      

            Assignee:
            backlog-server-servicearch [DO NOT USE] Backlog - Service Architecture
            Reporter:
            amirsaman.memaripour@mongodb.com Amirsaman Memaripour
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: