Add retry mechanics to pallet-scheduler (#3060)

Fixes #3014 

This PR adds retry mechanics to `pallet-scheduler`, as described in the
issue above.

Users can now set a retry configuration for a task so that, in case its
scheduled run fails, it will be retried after a number of blocks, for a
specified number of times or until it succeeds.

If a retried task runs successfully before running out of retries, its
remaining retry counter will be reset to the initial value. If a retried
task runs out of retries, it will be removed from the schedule.

Tasks which need to be scheduled for a retry are still subject to weight
metering and agenda space, same as a regular task. Periodic tasks will
have their periodic schedule put on hold while the task is retrying.

---------

Signed-off-by: georgepisaltu <george.pisaltu@parity.io>
Co-authored-by: command-bot <>
This commit is contained in:
georgepisaltu
2024-02-16 12:59:10 +02:00
committed by GitHub
parent ad68a05079
commit 9346019dad
9 changed files with 2292 additions and 377 deletions
+40
View File
@@ -51,6 +51,17 @@ pub mod logger {
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pallet::storage]
pub type Threshold<T: Config> = StorageValue<_, (BlockNumberFor<T>, BlockNumberFor<T>)>;
#[pallet::error]
pub enum Error<T> {
/// Under the threshold.
TooEarly,
/// Over the threshold.
TooLate,
}
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
@@ -89,6 +100,20 @@ pub mod logger {
});
Ok(())
}
#[pallet::call_index(2)]
#[pallet::weight(*weight)]
pub fn timed_log(origin: OriginFor<T>, i: u32, weight: Weight) -> DispatchResult {
let now = frame_system::Pallet::<T>::block_number();
let (start, end) = Threshold::<T>::get().unwrap_or((0u32.into(), u32::MAX.into()));
ensure!(now >= start, Error::<T>::TooEarly);
ensure!(now <= end, Error::<T>::TooLate);
Self::deposit_event(Event::Logged(i, weight));
Log::mutate(|log| {
log.push((origin.caller().clone(), i));
});
Ok(())
}
}
}
@@ -198,6 +223,21 @@ impl WeightInfo for TestWeightInfo {
fn cancel_named(_s: u32) -> Weight {
Weight::from_parts(50, 0)
}
fn schedule_retry(_s: u32) -> Weight {
Weight::from_parts(100000, 0)
}
fn set_retry() -> Weight {
Weight::from_parts(50, 0)
}
fn set_retry_named() -> Weight {
Weight::from_parts(50, 0)
}
fn cancel_retry() -> Weight {
Weight::from_parts(50, 0)
}
fn cancel_retry_named() -> Weight {
Weight::from_parts(50, 0)
}
}
parameter_types! {
pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) *