@@ -187,8 +187,10 @@ pub fn proc_macro_derive(input: TokenStream) -> TokenStream {
187
187
let handler = format_ident ! ( "handle_{}" , ident) ;
188
188
quote ! {
189
189
if let Some ( port) = fut. broker. #ident. enabled( ) {
190
+ any_handler_enabled |= true ;
190
191
loop {
191
192
match :: futures:: StreamExt :: poll_next_unpin( port, cx) {
193
+ // check if message is newer than fence
192
194
:: std:: task:: Poll :: Ready ( Some ( output) ) if output. source_ts > fence => {
193
195
match fut. broker. #handler( fut. plan, output) {
194
196
:: std:: result:: Result :: Ok ( :: agentwire:: BrokerFlow :: Break ) => {
@@ -210,9 +212,10 @@ pub fn proc_macro_derive(input: TokenStream) -> TokenStream {
210
212
}
211
213
}
212
214
:: std:: task:: Poll :: Ready ( :: std:: option:: Option :: Some ( _) ) => {
213
- continue ;
215
+ continue ; // skip message because its older than `fence`
214
216
}
215
217
:: std:: task:: Poll :: Ready ( :: std:: option:: Option :: None ) => {
218
+ // channel sender is dropped, which means agent terminated
216
219
return :: std:: task:: Poll :: Ready (
217
220
:: std:: result:: Result :: Err (
218
221
:: agentwire:: BrokerError :: AgentTerminated (
@@ -222,7 +225,7 @@ pub fn proc_macro_derive(input: TokenStream) -> TokenStream {
222
225
) ;
223
226
}
224
227
:: std:: task:: Poll :: Pending => {
225
- break ;
228
+ break ; // No more messages to process
226
229
}
227
230
}
228
231
}
@@ -249,7 +252,7 @@ pub fn proc_macro_derive(input: TokenStream) -> TokenStream {
249
252
} ,
250
253
) ;
251
254
let run = quote ! {
252
- # [ allow ( missing_docs ) ]
255
+ /// Future for [`#ident::run`].
253
256
pub struct #run_fut_name<' a> {
254
257
broker: & ' a mut #ident,
255
258
plan: & ' a mut dyn #broker_plan,
@@ -265,20 +268,32 @@ pub fn proc_macro_derive(input: TokenStream) -> TokenStream {
265
268
) -> :: std:: task:: Poll <Self :: Output > {
266
269
let fence = self . fence;
267
270
let fut = self . as_mut( ) . get_mut( ) ;
271
+ let mut any_handler_enabled = false ;
268
272
' outer: loop {
269
273
#( #run_handlers) *
270
274
#poll_extra
275
+ #[ allow( unreachable_code) ]
276
+ if !any_handler_enabled {
277
+ // Prevent infinite loop in edge case where no handlers are
278
+ // enabled.
279
+ return :: std:: task:: Poll :: Pending ;
280
+ }
271
281
}
282
+
272
283
}
273
284
}
274
285
275
286
impl #ident {
276
- # [ allow ( missing_docs ) ]
287
+ /// Equivalent to [`Self::run_with_fence()`] with a fence of `Instant::now()`.
277
288
pub fn run<' a>( & ' a mut self , plan: & ' a mut dyn #broker_plan) -> #run_fut_name<' a> {
278
289
Self :: run_with_fence( self , plan, :: std:: time:: Instant :: now( ) )
279
290
}
280
291
281
- #[ allow( missing_docs) ]
292
+ /// Runs the broker, filtering any events to only those with a timestamp
293
+ /// newer than `fence`.
294
+ ///
295
+ /// Events are fed the broker's `handle_*` functions, and `plan` is passed
296
+ /// there as an argument.
282
297
pub fn run_with_fence<' a>(
283
298
& ' a mut self ,
284
299
plan: & ' a mut dyn #broker_plan,
0 commit comments