@@ -4,9 +4,10 @@ use std::sync::Arc;
44use anyhow:: Context as _;
55use clap:: Parser ;
66use futures:: stream:: select_all;
7- use futures:: { StreamExt as _, TryStreamExt as _} ;
7+ use futures:: StreamExt as _;
8+ use tokio:: task:: JoinSet ;
89use tokio:: { select, signal} ;
9- use tracing:: { error, info, warn} ;
10+ use tracing:: { debug , error, info, warn} ;
1011
1112#[ derive( Parser , Debug ) ]
1213#[ command( author, version, about, long_about = None ) ]
@@ -42,29 +43,46 @@ async fn main() -> anyhow::Result<()> {
4243 . context ( "failed to serve `wasi:keyvalue`" ) ?;
4344 // NOTE: This will conflate all invocation streams into a single stream via `futures::stream::SelectAll`,
4445 // to customize this, iterate over the returned `invocations` and set up custom handling per export
45- let mut invocations = select_all ( invocations. into_iter ( ) . map (
46- |( instance, name, invocations) | {
47- invocations
48- . try_buffer_unordered ( 16 ) // handle up to 16 invocations concurrently
49- . map ( move |res| ( instance, name, res) )
50- } ,
51- ) ) ;
46+ let mut invocations = select_all (
47+ invocations
48+ . into_iter ( )
49+ . map ( |( instance, name, invocations) | invocations. map ( move |res| ( instance, name, res) ) ) ,
50+ ) ;
5251 let shutdown = signal:: ctrl_c ( ) ;
5352 let mut shutdown = pin ! ( shutdown) ;
53+ let mut tasks = JoinSet :: new ( ) ;
5454 loop {
5555 select ! {
5656 Some ( ( instance, name, res) ) = invocations. next( ) => {
5757 match res {
58- Ok ( ( ) ) => {
59- info!( instance, name, "invocation successfully handled" ) ;
58+ Ok ( fut) => {
59+ debug!( instance, name, "invocation accepted" ) ;
60+ tasks. spawn( async move {
61+ if let Err ( err) = fut. await {
62+ warn!( ?err, "failed to handle invocation" ) ;
63+ } else {
64+ info!( instance, name, "invocation successfully handled" ) ;
65+ }
66+ } ) ;
6067 }
6168 Err ( err) => {
6269 warn!( ?err, instance, name, "failed to accept invocation" ) ;
6370 }
6471 }
6572 }
73+ Some ( res) = tasks. join_next( ) => {
74+ if let Err ( err) = res {
75+ error!( ?err, "failed to join task" )
76+ }
77+ }
6678 res = & mut shutdown => {
6779 accept. abort( ) ;
80+ // wait for all invocations to complete
81+ while let Some ( res) = tasks. join_next( ) . await {
82+ if let Err ( err) = res {
83+ error!( ?err, "failed to join task" )
84+ }
85+ }
6886 return res. context( "failed to listen for ^C" )
6987 }
7088 }
0 commit comments