rocketmq_runtime/task_spawner.rs
1// Copyright 2023 The RocketMQ Rust Authors
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
15use std::future::Future;
16
17use tokio_util::sync::CancellationToken;
18
19use crate::critical::CriticalFailureState;
20use crate::error::RuntimeResult;
21use crate::task_group::TaskGroup;
22use crate::task_group::TaskGroupId;
23use crate::task_group::TaskId;
24use crate::task_group::TaskKind;
25
26/// Narrow capability for spawning work owned by an existing [`TaskGroup`].
27///
28/// Cloning this value shares lifecycle authority; it cannot create a runtime
29/// root, expose a raw Tokio handle, detach work, or outlive owner shutdown.
30#[derive(Debug, Clone)]
31pub struct TaskSpawner {
32 task_group: TaskGroup,
33}
34
35impl TaskSpawner {
36 pub(crate) fn new(task_group: TaskGroup) -> Self {
37 Self { task_group }
38 }
39
40 /// Returns the identity of the owned task group.
41 pub fn group_id(&self) -> TaskGroupId {
42 self.task_group.id()
43 }
44
45 /// Returns the diagnostic name of the owned task group.
46 pub fn group_name(&self) -> &str {
47 self.task_group.name()
48 }
49
50 /// Returns a child token cancelled by owner shutdown.
51 ///
52 /// Cancelling the returned token does not cancel the owning task group.
53 pub fn cancellation_token(&self) -> CancellationToken {
54 self.task_group.cancellation_token().child_token()
55 }
56
57 /// Registers `future` as parent-owned work.
58 ///
59 /// The future must be `Send` and tasks have no ordering guarantee relative
60 /// to other submissions. Owner shutdown cancels and awaits the registered
61 /// task according to the parent task group's deadline.
62 ///
63 /// # Errors
64 ///
65 /// Returns an error when the parent group is shutting down or closed.
66 pub fn spawn<F>(&self, name: impl Into<crate::TaskName>, kind: TaskKind, future: F) -> RuntimeResult<TaskId>
67 where
68 F: Future<Output = ()> + Send + 'static,
69 {
70 self.task_group.spawn(name, kind, future)
71 }
72
73 /// Registers a long-lived service future with a custom shutdown protocol.
74 ///
75 /// The future must observe a cancellation token and perform its own
76 /// ordered cleanup. Use [`Self::spawn_cancellable_service`] when owner
77 /// cancellation may drop the future immediately.
78 ///
79 /// # Errors
80 ///
81 /// Returns an error when the parent group is shutting down or closed.
82 pub fn spawn_service<F>(&self, name: impl Into<crate::TaskName>, future: F) -> RuntimeResult<TaskId>
83 where
84 F: Future<Output = ()> + Send + 'static,
85 {
86 self.task_group.spawn_service(name, future)
87 }
88
89 /// Registers a service that exits when either its future completes or its owner is cancelled.
90 ///
91 /// # Errors
92 ///
93 /// Returns an error when the parent group is shutting down or closed.
94 pub fn spawn_cancellable_service<F>(&self, name: impl Into<crate::TaskName>, future: F) -> RuntimeResult<TaskId>
95 where
96 F: Future<Output = ()> + Send + 'static,
97 {
98 self.task_group.spawn_cancellable_service(name, future)
99 }
100
101 /// Registers parent-owned work whose panic is recorded as a critical failure.
102 ///
103 /// The failure record stays pending until a handler takes it, so a full
104 /// notification channel cannot lose the fact that the task failed.
105 ///
106 /// # Errors
107 ///
108 /// Returns an error when the parent group is shutting down or closed.
109 pub fn spawn_critical<F>(
110 &self,
111 name: impl Into<crate::TaskName>,
112 kind: TaskKind,
113 failures: CriticalFailureState,
114 future: F,
115 ) -> RuntimeResult<TaskId>
116 where
117 F: Future<Output = ()> + Send + 'static,
118 {
119 self.task_group.spawn_critical(name, kind, failures, future)
120 }
121
122 /// Registers a critical service that must run until its owner is cancelled.
123 ///
124 /// A panic and a return before owner cancellation are both recorded; owner
125 /// cancellation is an expected exit and records nothing.
126 ///
127 /// # Errors
128 ///
129 /// Returns an error when the parent group is shutting down or closed.
130 pub fn spawn_critical_service<F>(
131 &self,
132 name: impl Into<crate::TaskName>,
133 failures: CriticalFailureState,
134 future: F,
135 ) -> RuntimeResult<TaskId>
136 where
137 F: Future<Output = ()> + Send + 'static,
138 {
139 self.task_group.spawn_critical_service(name, failures, future)
140 }
141}