@@ -171,8 +171,10 @@ pub fn proc_macro_derive(input: TokenStream) -> TokenStream {
171
171
let handler = format_ident ! ( "handle_{}" , ident) ;
172
172
quote ! {
173
173
if let Some ( port) = fut. broker. #ident. enabled( ) {
174
+ any_handler_enabled |= true ;
174
175
loop {
175
176
match :: futures:: StreamExt :: poll_next_unpin( port, cx) {
177
+ // check if message is newer than fence
176
178
:: std:: task:: Poll :: Ready ( Some ( output) ) if output. source_ts > fence => {
177
179
match fut. broker. #handler( fut. plan, output) {
178
180
:: std:: result:: Result :: Ok ( :: agentwire:: BrokerFlow :: Break ) => {
@@ -194,9 +196,10 @@ pub fn proc_macro_derive(input: TokenStream) -> TokenStream {
194
196
}
195
197
}
196
198
:: std:: task:: Poll :: Ready ( :: std:: option:: Option :: Some ( _) ) => {
197
- continue ;
199
+ continue ; // skip message because its older than `fence`
198
200
}
199
201
:: std:: task:: Poll :: Ready ( :: std:: option:: Option :: None ) => {
202
+ // channel sender is dropped, which means agent terminated
200
203
return :: std:: task:: Poll :: Ready (
201
204
:: std:: result:: Result :: Err (
202
205
:: agentwire:: BrokerError :: AgentTerminated (
@@ -206,7 +209,7 @@ pub fn proc_macro_derive(input: TokenStream) -> TokenStream {
206
209
) ;
207
210
}
208
211
:: std:: task:: Poll :: Pending => {
209
- break ;
212
+ break ; // No more messages to process
210
213
}
211
214
}
212
215
}
@@ -231,7 +234,7 @@ pub fn proc_macro_derive(input: TokenStream) -> TokenStream {
231
234
}
232
235
} ) ;
233
236
let run = quote ! {
234
- # [ allow ( missing_docs ) ]
237
+ /// Future for [`#ident::run`].
235
238
pub struct #run_fut_name<' a> {
236
239
broker: & ' a mut #ident,
237
240
plan: & ' a mut dyn #broker_plan,
@@ -247,20 +250,31 @@ pub fn proc_macro_derive(input: TokenStream) -> TokenStream {
247
250
) -> :: std:: task:: Poll <Self :: Output > {
248
251
let fence = self . fence;
249
252
let fut = self . as_mut( ) . get_mut( ) ;
253
+ let mut any_handler_enabled = false ;
250
254
' outer: loop {
251
255
#( #run_handlers) *
252
256
#poll_extra
257
+ if !any_handler_enabled {
258
+ // Prevent infinite loop in edge case where no handlers are
259
+ // enabled.
260
+ return :: std:: task:: Poll :: Pending ;
261
+ }
253
262
}
263
+
254
264
}
255
265
}
256
266
257
267
impl #ident {
258
- # [ allow ( missing_docs ) ]
268
+ /// Equivalent to [`Self::run_with_fence()`] with a fence of `Instant::now()`.
259
269
pub fn run<' a>( & ' a mut self , plan: & ' a mut dyn #broker_plan) -> #run_fut_name<' a> {
260
270
Self :: run_with_fence( self , plan, :: std:: time:: Instant :: now( ) )
261
271
}
262
272
263
- #[ allow( missing_docs) ]
273
+ /// Runs the broker, filtering any events to only those with a timestamp
274
+ /// newer than `fence`.
275
+ ///
276
+ /// Events are fed the broker's `handle_*` functions, and `plan` is passed
277
+ /// there as an argument.
264
278
pub fn run_with_fence<' a>(
265
279
& ' a mut self ,
266
280
plan: & ' a mut dyn #broker_plan,
0 commit comments