| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2012 Google Inc. |
| 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at |
| 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. |
| 14 |
| 15 // |
| 16 // An abstraction for scheduling recurring tasks. Combines idempotent scheduling |
| 17 // and smearing with conditional retries and exponential backoff. Does not |
| 18 // implement throttling. Designed to support a variety of use cases, including |
| 19 // the following capabilities. |
| 20 // |
| 21 // * Idempotent scheduling, e.g., ensuring that a batching task is scheduled |
| 22 // exactly once. |
| 23 // * Recurring tasks, e.g., periodic heartbeats. |
| 24 // * Retriable actions aimed at state change, e.g., sending initialization |
| 25 // messages. |
| 26 // |
| 27 // Each instance of this class manages the state for a single task. See the |
| 28 // invalidation-client-impl.cc for examples. |
| 29 |
| 30 #ifndef GOOGLE_CACHEINVALIDATION_IMPL_RECURRING_TASK_H_ |
| 31 #define GOOGLE_CACHEINVALIDATION_IMPL_RECURRING_TASK_H_ |
| 32 |
| 33 #include "google/cacheinvalidation/include/system-resources.h" |
| 34 #include "google/cacheinvalidation/impl/exponential-backoff-delay-generator.h" |
| 35 #include "google/cacheinvalidation/impl/smearer.h" |
| 36 |
| 37 namespace invalidation { |
| 38 |
| 39 class RecurringTask { |
| 40 public: |
| 41 /* Creates a recurring task with the given parameters. The specs of the |
| 42 * parameters are given in the instance variables. |
| 43 * |
| 44 * The created task is first scheduled with a smeared delay of |
| 45 * |initial_delay|. If the |this->run()| returns true on its execution, the |
| 46 * task is rescheduled after a |timeout_delay| + smeared delay of |
| 47 * |initial_delay| or |timeout_delay| + |delay_generator->GetNextDelay()| |
| 48 * depending on whether the |delay_generator| is null or not. |
| 49 * |
| 50 * Space for |scheduler|, |logger|, |smearer| is owned by the caller. |
| 51 * Space for |delay_generator| is owned by the callee. |
| 52 */ |
| 53 RecurringTask(string name, Scheduler* scheduler, Logger* logger, |
| 54 Smearer* smearer, ExponentialBackoffDelayGenerator* delay_generator, |
| 55 TimeDelta initial_delay, TimeDelta timeout_delay); |
| 56 |
| 57 virtual ~RecurringTask() {} |
| 58 |
| 59 /* Run the task and return true if the task should be rescheduled after a |
| 60 * timeout. If false is returned, the task is not scheduled again until |
| 61 * |ensure_scheduled| is called again. |
| 62 */ |
| 63 virtual bool RunTask() = 0; |
| 64 |
| 65 /* Ensures that the task is scheduled (with |debug_reason| as the reason to be |
| 66 * printed for debugging purposes). If the task has been scheduled, it is |
| 67 * not scheduled again. |
| 68 * |
| 69 * REQUIRES: Must be called from the scheduler thread. |
| 70 */ |
| 71 void EnsureScheduled(string debug_reason); |
| 72 |
| 73 /* Space for the returned Smearer is still owned by this class. */ |
| 74 Smearer* smearer() { |
| 75 return smearer_; |
| 76 } |
| 77 |
| 78 private: |
| 79 /* Run the task and check if it needs to be rescheduled. If so, reschedule it |
| 80 * after the appropriate delay. |
| 81 */ |
| 82 void RunTaskAndRescheduleIfNeeded(); |
| 83 |
| 84 /* Ensures that the task is scheduled if it is already not scheduled. If |
| 85 * already scheduled, this method is a no-op. If |is_retry| is |false|, smears |
| 86 * the |initial_delay_| and uses that delay for scheduling. If |is_retry| is |
| 87 * true, it determines the new delay to be |
| 88 * |timeout_delay_ + delay_generator.GetNextDelay()| if |delay_generator| is |
| 89 * non-null. If |delay_generator| is null, schedules the task after a delay of |
| 90 * |timeout_delay_| + smeared value of |initial_delay_|. |
| 91 * |
| 92 * REQUIRES: Must be called from the scheduler thread. |
| 93 */ |
| 94 void EnsureScheduled(bool is_retry, string debug_reason); |
| 95 |
| 96 /* Name of the task (for debugging purposes mostly). */ |
| 97 string name_; |
| 98 |
| 99 /* Scheduler for the scheduling the task as needed. */ |
| 100 Scheduler* scheduler_; |
| 101 |
| 102 /* A logger. */ |
| 103 Logger* logger_; |
| 104 |
| 105 /* A smearer for spreading the delays. */ |
| 106 Smearer* smearer_; |
| 107 |
| 108 /* A delay generator for exponential backoff. */ |
| 109 scoped_ptr<ExponentialBackoffDelayGenerator> delay_generator_; |
| 110 |
| 111 /* |
| 112 * The time after which the task is scheduled first. If no delayGenerator is |
| 113 * specified, this is also the delay used for retries. |
| 114 */ |
| 115 TimeDelta initial_delay_; |
| 116 |
| 117 /* For a task that is retried, add this time to the delay. */ |
| 118 TimeDelta timeout_delay_; |
| 119 |
| 120 /* If the task has been currently scheduled. */ |
| 121 bool is_scheduled_; |
| 122 |
| 123 DISALLOW_COPY_AND_ASSIGN(RecurringTask); |
| 124 }; |
| 125 |
| 126 } // namespace invalidation |
| 127 |
| 128 #endif // GOOGLE_CACHEINVALIDATION_IMPL_RECURRING_TASK_H_ |
| OLD | NEW |