pallet-message-queue: add queue pausing (#14318)

* pallet-message-queue: add queue pausing

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Fix build

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Remove check

Otherwise it would not start servicing queues that started paused
and became unpaused afterwards.

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

---------

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
This commit is contained in:
Oliver Tale-Yazdi
2023-06-28 10:58:31 +02:00
committed by GitHub
parent 2119c80225
commit 4249643df2
8 changed files with 269 additions and 63 deletions
+23 -2
View File
@@ -195,7 +195,7 @@ use frame_support::{
pallet_prelude::*,
traits::{
DefensiveTruncateFrom, EnqueueMessage, ExecuteOverweightError, Footprint, ProcessMessage,
ProcessMessageError, ServiceQueues,
ProcessMessageError, QueuePausedQuery, ServiceQueues,
},
BoundedSlice, CloneNoBound, DefaultNoBound,
};
@@ -473,6 +473,13 @@ pub mod pallet {
/// removed.
type QueueChangeHandler: OnQueueChanged<<Self::MessageProcessor as ProcessMessage>::Origin>;
/// Queried by the pallet to check whether a queue can be serviced.
///
/// This also applies to manual servicing via `execute_overweight` and `service_queues`. The
/// value of this is only polled once before servicing the queue. This means that changes to
/// it that happen *within* the servicing will not be reflected.
type QueuePausedQuery: QueuePausedQuery<<Self::MessageProcessor as ProcessMessage>::Origin>;
/// The size of the page; this implies the maximum message size which can be sent.
///
/// A good value depends on the expected message sizes, their weights, the weight that is
@@ -534,6 +541,10 @@ pub mod pallet {
/// Such errors are expected, but not guaranteed, to resolve themselves eventually through
/// retrying.
TemporarilyUnprocessable,
/// The queue is paused and no message can be executed from it.
///
/// This can change at any time and may resolve in the future by re-trying.
QueuePaused,
}
/// The index of the first and last (non-empty) pages.
@@ -803,6 +814,8 @@ impl<T: Config> Pallet<T> {
weight_limit: Weight,
) -> Result<Weight, Error<T>> {
let mut book_state = BookStateFor::<T>::get(&origin);
ensure!(!T::QueuePausedQuery::is_paused(&origin), Error::<T>::QueuePaused);
let mut page = Pages::<T>::get(&origin, page_index).ok_or(Error::<T>::NoPage)?;
let (pos, is_processed, payload) =
page.peek_index(index.into() as usize).ok_or(Error::<T>::NoMessage)?;
@@ -943,6 +956,10 @@ impl<T: Config> Pallet<T> {
let mut book_state = BookStateFor::<T>::get(&origin);
let mut total_processed = 0;
if T::QueuePausedQuery::is_paused(&origin) {
let next_ready = book_state.ready_neighbours.as_ref().map(|x| x.next.clone());
return (false, next_ready)
}
while book_state.end > book_state.begin {
let (processed, status) =
@@ -1284,7 +1301,11 @@ impl<T: Config> ServiceQueues for Pallet<T> {
Pallet::<T>::do_execute_overweight(message_origin, page, index, weight.remaining()).map_err(
|e| match e {
Error::<T>::InsufficientWeight => ExecuteOverweightError::InsufficientWeight,
_ => ExecuteOverweightError::NotFound,
Error::<T>::AlreadyProcessed => ExecuteOverweightError::AlreadyProcessed,
Error::<T>::QueuePaused => ExecuteOverweightError::QueuePaused,
Error::<T>::NoPage | Error::<T>::NoMessage | Error::<T>::Queued =>
ExecuteOverweightError::NotFound,
_ => ExecuteOverweightError::Other,
},
)
}