1use std::error::Error;
4use std::fmt;
5
6use crate::{
7 BoxFuture, ExecutionCorrelation, FailureSummary, JobParameters, StopToken,
8 TaskletExecutionOutcome,
9};
10
11#[derive(Clone, Copy, Debug)]
13pub struct ListenerContext<'a> {
14 correlation: &'a ExecutionCorrelation,
15 parameters: &'a JobParameters,
16 stop: &'a StopToken,
17}
18
19impl<'a> ListenerContext<'a> {
20 pub(crate) const fn new(
21 correlation: &'a ExecutionCorrelation,
22 parameters: &'a JobParameters,
23 stop: &'a StopToken,
24 ) -> Self {
25 Self {
26 correlation,
27 parameters,
28 stop,
29 }
30 }
31
32 #[must_use]
34 pub const fn correlation(&self) -> &'a ExecutionCorrelation {
35 self.correlation
36 }
37
38 #[must_use]
42 pub const fn parameters(&self) -> &'a JobParameters {
43 self.parameters
44 }
45
46 #[must_use]
48 pub const fn stop_token(&self) -> &'a StopToken {
49 self.stop
50 }
51}
52
53pub trait JobExecutionListener: Send + Sync {
55 fn before_job<'a>(
57 &'a self,
58 context: ListenerContext<'a>,
59 ) -> BoxFuture<'a, Result<(), ListenerError>>;
60
61 fn after_job<'a>(
64 &'a self,
65 context: ListenerContext<'a>,
66 outcome: TaskletExecutionOutcome,
67 ) -> BoxFuture<'a, Result<(), ListenerError>>;
68}
69
70pub trait StepExecutionListener: Send + Sync {
72 fn before_step<'a>(
74 &'a self,
75 context: ListenerContext<'a>,
76 ) -> BoxFuture<'a, Result<(), ListenerError>>;
77
78 fn after_step<'a>(
81 &'a self,
82 context: ListenerContext<'a>,
83 outcome: TaskletExecutionOutcome,
84 ) -> BoxFuture<'a, Result<(), ListenerError>>;
85}
86
87#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
89pub struct ListenerError;
90
91impl ListenerError {
92 #[must_use]
94 pub const fn new() -> Self {
95 Self
96 }
97
98 #[must_use]
100 pub fn from_error(error: impl Error + Send + Sync + 'static) -> Self {
101 drop(error);
102 Self
103 }
104}
105
106impl fmt::Display for ListenerError {
107 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
108 formatter.write_str("the execution listener failed")
109 }
110}
111
112impl Error for ListenerError {}
113
114#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
116#[non_exhaustive]
117pub enum ListenerPhase {
118 BeforeJob,
120 BeforeStep,
122 AfterStep,
124 AfterJob,
126}
127
128#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
130#[non_exhaustive]
131pub enum ListenerFailureKind {
132 Error,
134 Panic,
136}
137
138#[derive(Clone, Copy, Debug, Eq, PartialEq)]
140pub struct ListenerFailure {
141 phase: ListenerPhase,
142 registration_index: usize,
143 kind: ListenerFailureKind,
144 summary: FailureSummary,
145}
146
147impl ListenerFailure {
148 pub(crate) const fn new(
149 phase: ListenerPhase,
150 registration_index: usize,
151 kind: ListenerFailureKind,
152 summary: FailureSummary,
153 ) -> Self {
154 Self {
155 phase,
156 registration_index,
157 kind,
158 summary,
159 }
160 }
161
162 #[must_use]
164 pub const fn phase(self) -> ListenerPhase {
165 self.phase
166 }
167
168 #[must_use]
170 pub const fn registration_index(self) -> usize {
171 self.registration_index
172 }
173
174 #[must_use]
176 pub const fn kind(self) -> ListenerFailureKind {
177 self.kind
178 }
179
180 #[must_use]
182 pub const fn summary(self) -> FailureSummary {
183 self.summary
184 }
185}