Introduce scheduler and use it for the democracy dispatch queue (#5412)

* Initial draft of the logic

* Build and tests

* Make work with new initialize infratructure.

* Update frame/scheduler/src/lib.rs

Co-Authored-By: Marcio Diaz <marcio.diaz@gmail.com>

* Update frame/scheduler/src/lib.rs

Co-Authored-By: Marcio Diaz <marcio.diaz@gmail.com>

* Update frame/scheduler/src/lib.rs

Co-Authored-By: Marcio Diaz <marcio.diaz@gmail.com>

* Update frame/scheduler/src/lib.rs

Co-Authored-By: Marcio Diaz <marcio.diaz@gmail.com>

* Fix test

* Update frame/scheduler/src/lib.rs

Co-Authored-By: Marcio Diaz <marcio.diaz@gmail.com>

* Rejig interface to make it more useful for democracy.

* Try to get democraxy module to make use of scheduler.

* Make democracy use scheduler.

* Use actual max weight for enactent

* Remove TODO

* Fix runtime build

* Minor cleanup

* Fix scheduler.

* Fix benchmarks

* Fix

* Fix

* Fix

* More bench fixes

* Fix

* Fix.

* Add more bench constants.

* Fix cancel_queued bench.

* Fix test comment.

* Update frame/scheduler/src/lib.rs

Co-Authored-By: Marcio Diaz <marcio.diaz@gmail.com>

Co-authored-by: Marcio Diaz <marcio.diaz@gmail.com>
This commit is contained in:
Gavin Wood
2020-04-01 15:52:39 +02:00
committed by GitHub
parent 433824511e
commit eac1a1964e
16 changed files with 825 additions and 121 deletions
+79 -1
View File
@@ -19,7 +19,7 @@
//! NOTE: If you're looking for `parameter_types`, it has moved in to the top-level module.
use sp_std::{prelude::*, result, marker::PhantomData, ops::Div, fmt::Debug};
use codec::{FullCodec, Codec, Encode, Decode};
use codec::{FullCodec, Codec, Encode, Decode, EncodeLike};
use sp_core::u32_trait::Value as U32;
use sp_runtime::{
RuntimeDebug,
@@ -1144,6 +1144,84 @@ pub trait OffchainWorker<BlockNumber> {
fn offchain_worker(_n: BlockNumber) {}
}
pub mod schedule {
use super::*;
/// Information relating to the period of a scheduled task. First item is the length of the
/// period and the second is the number of times it should be executed in total before the task
/// is considered finished and removed.
pub type Period<BlockNumber> = (BlockNumber, u32);
/// Priority with which a call is scheduled. It's just a linear amount with lowest values meaning
/// higher priority.
pub type Priority = u8;
/// The highest priority. We invert the value so that normal sorting will place the highest
/// priority at the beginning of the list.
pub const HIGHEST_PRORITY: Priority = 0;
/// Anything of this value or lower will definitely be scheduled on the block that they ask for, even
/// if it breaches the `MaximumWeight` limitation.
pub const HARD_DEADLINE: Priority = 63;
/// The lowest priority. Most stuff should be around here.
pub const LOWEST_PRORITY: Priority = 255;
/// A type that can be used as a scheduler.
pub trait Anon<BlockNumber, Call> {
/// An address which can be used for removing a scheduled task.
type Address: Codec + Clone + Eq + EncodeLike + Debug;
/// Schedule a one-off dispatch to happen at the beginning of some block in the future.
///
/// This is not named.
///
/// Infallible.
fn schedule(
when: BlockNumber,
maybe_periodic: Option<Period<BlockNumber>>,
priority: Priority,
call: Call
) -> Self::Address;
/// Cancel a scheduled task. If periodic, then it will cancel all further instances of that,
/// also.
///
/// Will return an error if the `address` is invalid.
///
/// NOTE: This guaranteed to work only *before* the point that it is due to be executed.
/// If it ends up being delayed beyond the point of execution, then it cannot be cancelled.
///
/// NOTE2: This will not work to cancel periodic tasks after their initial execution. For
/// that, you must name the task explicitly using the `Named` trait.
fn cancel(address: Self::Address) -> Result<(), ()>;
}
/// A type that can be used as a scheduler.
pub trait Named<BlockNumber, Call> {
/// An address which can be used for removing a scheduled task.
type Address: Codec + Clone + Eq + EncodeLike + sp_std::fmt::Debug;
/// Schedule a one-off dispatch to happen at the beginning of some block in the future.
///
/// - `id`: The identity of the task. This must be unique and will return an error if not.
fn schedule_named(
id: impl Encode,
when: BlockNumber,
maybe_periodic: Option<Period<BlockNumber>>,
priority: Priority,
call: Call
) -> Result<Self::Address, ()>;
/// Cancel a scheduled, named task. If periodic, then it will cancel all further instances
/// of that, also.
///
/// Will return an error if the `id` is invalid.
///
/// NOTE: This guaranteed to work only *before* the point that it is due to be executed.
/// If it ends up being delayed beyond the point of execution, then it cannot be cancelled.
fn cancel_named(id: impl Encode) -> Result<(), ()>;
}
}
#[cfg(test)]
mod tests {
use super::*;