watchexec_supervisor/job/
messages.rs1use std::{
2 future::Future,
3 pin::Pin,
4 task::{Context, Poll},
5 time::Duration,
6};
7
8use futures::{future::select, FutureExt};
9use watchexec_signals::Signal;
10
11use crate::flag::Flag;
12
13use super::task::{
14 AsyncErrorHandler, AsyncFunc, AsyncSpawnHook, SyncErrorHandler, SyncFunc, SyncSpawnHook,
15};
16
17pub enum Control {
22 Start,
24 Stop,
26 GracefulStop {
28 signal: Signal,
30 grace: Duration,
32 },
33 TryRestart,
35 TryGracefulRestart {
37 signal: Signal,
39 grace: Duration,
41 },
42 ContinueTryGracefulRestart,
44 Signal(Signal),
46 Delete,
48
49 NextEnding,
51
52 SyncFunc(SyncFunc),
54 AsyncFunc(AsyncFunc),
56
57 SetSyncSpawnHook(SyncSpawnHook),
59 SetAsyncSpawnHook(AsyncSpawnHook),
61 UnsetSpawnHook,
63 SetSyncErrorHandler(SyncErrorHandler),
65 SetAsyncErrorHandler(AsyncErrorHandler),
67 UnsetErrorHandler,
69}
70
71impl std::fmt::Debug for Control {
72 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73 match self {
74 Self::Start => f.debug_struct("Start").finish(),
75 Self::Stop => f.debug_struct("Stop").finish(),
76 Self::GracefulStop { signal, grace } => f
77 .debug_struct("GracefulStop")
78 .field("signal", signal)
79 .field("grace", grace)
80 .finish(),
81 Self::TryRestart => f.debug_struct("TryRestart").finish(),
82 Self::TryGracefulRestart { signal, grace } => f
83 .debug_struct("TryGracefulRestart")
84 .field("signal", signal)
85 .field("grace", grace)
86 .finish(),
87 Self::ContinueTryGracefulRestart => {
88 f.debug_struct("ContinueTryGracefulRestart").finish()
89 }
90 Self::Signal(signal) => f.debug_struct("Signal").field("signal", signal).finish(),
91 Self::Delete => f.debug_struct("Delete").finish(),
92
93 Self::NextEnding => f.debug_struct("NextEnding").finish(),
94
95 Self::SyncFunc(_) => f.debug_struct("SyncFunc").finish_non_exhaustive(),
96 Self::AsyncFunc(_) => f.debug_struct("AsyncFunc").finish_non_exhaustive(),
97
98 Self::SetSyncSpawnHook(_) => f.debug_struct("SetSyncSpawnHook").finish_non_exhaustive(),
99 Self::SetAsyncSpawnHook(_) => {
100 f.debug_struct("SetSpawnAsyncHook").finish_non_exhaustive()
101 }
102 Self::UnsetSpawnHook => f.debug_struct("UnsetSpawnHook").finish(),
103 Self::SetSyncErrorHandler(_) => f
104 .debug_struct("SetSyncErrorHandler")
105 .finish_non_exhaustive(),
106 Self::SetAsyncErrorHandler(_) => f
107 .debug_struct("SetAsyncErrorHandler")
108 .finish_non_exhaustive(),
109 Self::UnsetErrorHandler => f.debug_struct("UnsetErrorHandler").finish(),
110 }
111 }
112}
113
114#[derive(Debug)]
115pub struct ControlMessage {
116 pub control: Control,
117 pub done: Flag,
118}
119
120#[derive(Debug, Clone)]
128pub struct Ticket {
129 pub(crate) job_gone: Flag,
130 pub(crate) control_done: Flag,
131}
132
133impl Ticket {
134 pub(crate) fn cancelled() -> Self {
135 Self {
136 job_gone: Flag::new(true),
137 control_done: Flag::new(true),
138 }
139 }
140}
141
142impl Future for Ticket {
143 type Output = ();
144
145 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
146 Pin::new(&mut select(self.job_gone.clone(), self.control_done.clone()).map(|_| ())).poll(cx)
147 }
148}