void TimeoutController::runTimeouts(TimePoint time) {
  auto now = Clock::now();
  // Make sure we don't skip some events if function was run before actual time.
  if (time < now) {
    time = now;
  }
  if (nextTimeout_ > time) {
    return;
  }

  nextTimeout_ = TimePoint::max();

  for (auto& bucket : timeoutHandleBuckets_) {
    auto& list = bucket.second;

    for (auto it = list.begin(); it != list.end();) {
      if (it->timeout_ > time) {
        nextTimeout_ = std::min(nextTimeout_, it->timeout_);
        break;
      }

      it->onTimeout();
      it = list.erase(it);
    }
  }

  if (nextTimeout_ != TimePoint::max()) {
    scheduleRun();
  }
}
Exemple #2
0
void
Work::complete(CompleteResult result)
{
    CLOG(DEBUG, "Work") << "completed " << getUniqueName();
    auto& succ =
        mApp.getMetrics().NewMeter({"work", "unit", "success"}, "unit");
    auto& fail =
        mApp.getMetrics().NewMeter({"work", "unit", "failure"}, "unit");

    switch (result)
    {
    case WORK_COMPLETE_OK:
        setState(onSuccess());
        break;
    case WORK_COMPLETE_FAILURE:
        setState(WORK_FAILURE_RETRY);
        break;
    case WORK_COMPLETE_FATAL:
        setState(WORK_FAILURE_FATAL);
        break;
    }

    switch (getState())
    {
    case WORK_SUCCESS:
        succ.Mark();
        CLOG(DEBUG, "Work")
            << "notifying parent of successful " << getUniqueName();
        notifyParent();
        break;

    case WORK_FAILURE_RETRY:
        fail.Mark();
        onFailureRetry();
        scheduleRetry();
        break;

    case WORK_FAILURE_RAISE:
    case WORK_FAILURE_FATAL:
        fail.Mark();
        onFailureRaise();
        CLOG(DEBUG, "Work") << "notifying parent of failed " << getUniqueName();
        notifyParent();
        break;

    case WORK_PENDING:
        succ.Mark();
        advance();
        break;

    case WORK_RUNNING:
        succ.Mark();
        scheduleRun();
        break;

    default:
        assert(false);
        break;
    }
}
Exemple #3
0
void
Work::advance()
{
    if (getState() != WORK_PENDING)
    {
        return;
    }

    CLOG(DEBUG, "Work") << "advancing " << getUniqueName();
    advanceChildren();
    if (allChildrenSuccessful())
    {
        CLOG(DEBUG, "Work") << "all " << mChildren.size() << " children of "
                            << getUniqueName() << " successful, scheduling run";
        scheduleRun();
    }
    else if (anyChildFatalFailure())
    {
        CLOG(DEBUG, "Work") << "some of " << mChildren.size() << " children of "
                            << getUniqueName() << " fatally failed, scheduling "
                            << "fatal failure";
        scheduleFatalFailure();
    }
    else if (anyChildRaiseFailure())
    {
        CLOG(DEBUG, "Work") << "some of " << mChildren.size() << " children of "
                            << getUniqueName() << " failed, scheduling failure";
        scheduleFailure();
    }
}
Exemple #4
0
void TimeoutController::runTimeouts(TimePoint time) {
  auto now = Clock::now();
  // Make sure we don't skip some events if function was run before actual time.
  if (time < now) {
    time = now;
  }
  if (nextTimeout_ > time) {
    return;
  }

  nextTimeout_ = TimePoint::max();

  for (auto& bucket : timeoutHandleBuckets_) {
    auto& list = *bucket.second;

    while (!list.empty()) {
      if (!list.front().canceled) {
        if (list.front().timeout > time) {
          nextTimeout_ = std::min(nextTimeout_, list.front().timeout);
          break;
        }

        list.front().func();
      }
      list.pop();
    }
  }

  if (nextTimeout_ != TimePoint::max()) {
    scheduleRun();
  }
}
Exemple #5
0
intptr_t TimeoutController::registerTimeout(
    std::function<void()> f,
    Duration duration) {
  auto& list = [&]() -> TimeoutHandleList& {
    for (auto& bucket : timeoutHandleBuckets_) {
      if (bucket.first == duration) {
        return *bucket.second;
      }
    }

    timeoutHandleBuckets_.emplace_back(
        duration, std::make_unique<TimeoutHandleList>());
    return *timeoutHandleBuckets_.back().second;
  }();

  auto timeout = Clock::now() + duration;
  list.emplace(std::move(f), timeout, list);

  if (timeout < nextTimeout_) {
    nextTimeout_ = timeout;
    scheduleRun();
  }

  return reinterpret_cast<intptr_t>(&list.back());
}
void TimeoutController::registerTimeout(TimeoutHandle& th, Duration duration) {
  auto& list = [&]() -> TimeoutHandleList& {
    for (auto& bucket : timeoutHandleBuckets_) {
      if (bucket.first == duration) {
        return bucket.second;
      }
    }

    timeoutHandleBuckets_.emplace_back(duration, TimeoutHandleList());
    return timeoutHandleBuckets_.back().second;
  }();

  list.push_back(th);

  th.timeout_ = Clock::now() + duration;
  if (th.timeout_ < nextTimeout_) {
    nextTimeout_ = th.timeout_;
    scheduleRun();
  }
}