Attribute Macro frame_support_procedural::tasks_experimental
source · #[tasks_experimental]
Expand description
Allows you to define some service work that can be recognized by a script or an off-chain worker.
Such a script can then create and submit all such work items at any given time.
These work items are defined as instances of the Task
trait (found at
frame_support::traits::Task
). pallet:tasks_experimental
when
attached to an impl
block inside a pallet, will generate an enum Task<T>
whose variants
are mapped to functions inside this impl
block.
Each such function must have the following set of attributes:
All of such Tasks are then aggregated into a RuntimeTask
by
construct_runtime
.
Finally, the RuntimeTask
can then used by a script or off-chain worker to create and
submit such tasks via an extrinsic defined in frame_system
called do_task
.
When submitted as unsigned transactions (for example via an off-chain workder), note that the tasks will be executed in a random order.
§Example
#[pallet::tasks_experimental]
impl<T: Config> Pallet<T> {
/// Add a pair of numbers into the totals and remove them.
#[pallet::task_list(Numbers::<T>::iter_keys())]
#[pallet::task_condition(|i| Numbers::<T>::contains_key(i))]
#[pallet::task_weight(0.into())]
#[pallet::task_index(0)]
pub fn add_number_into_total(i: u32) -> DispatchResult {
let v = Numbers::<T>::take(i).ok_or(Error::<T>::NotFound)?;
Total::<T>::mutate(|(total_keys, total_values)| {
*total_keys += i;
*total_values += v;
});
Ok(())
}
}
Now, this can be executed as follows:
#[test]
fn tasks_work() {
super::new_test_ext().execute_with(|| {
Numbers::<Runtime>::insert(0, 1);
let task = RuntimeTask::System(super::frame_system::Task::<Runtime>::AddNumberIntoTotal {
i: 0u32,
});
assert_ok!(System::do_task(RuntimeOrigin::signed(1), task.clone(),));
assert_eq!(Numbers::<Runtime>::get(0), None);
assert_eq!(Total::<Runtime>::get(), (0, 1));
});
}