@@ -17,6 +17,7 @@ use futures::stream::BoxStream;
1717use futures:: { SinkExt , Stream , StreamExt , TryStreamExt } ;
1818use iroh_bytes:: provider:: AddProgress ;
1919use iroh_bytes:: store:: ValidateProgress ;
20+ use iroh_bytes:: util:: runtime;
2021use iroh_bytes:: Hash ;
2122use iroh_bytes:: { BlobFormat , Tag } ;
2223use iroh_net:: { key:: PublicKey , magic_endpoint:: ConnectionInfo , PeerAddr } ;
@@ -67,11 +68,14 @@ where
6768 C : ServiceConnection < ProviderService > ,
6869{
6970 /// Create a new high-level client to a Iroh node from the low-level RPC client.
70- pub fn new ( rpc : RpcClient < ProviderService , C > ) -> Self {
71+ pub fn new ( rpc : RpcClient < ProviderService , C > , rt : runtime :: Handle ) -> Self {
7172 Self {
7273 node : NodeClient { rpc : rpc. clone ( ) } ,
7374 blobs : BlobsClient { rpc : rpc. clone ( ) } ,
74- docs : DocsClient { rpc : rpc. clone ( ) } ,
75+ docs : DocsClient {
76+ rpc : rpc. clone ( ) ,
77+ rt,
78+ } ,
7579 authors : AuthorsClient { rpc : rpc. clone ( ) } ,
7680 tags : TagsClient { rpc } ,
7781 }
@@ -129,6 +133,7 @@ where
129133#[ derive( Debug , Clone ) ]
130134pub struct DocsClient < C > {
131135 rpc : RpcClient < ProviderService , C > ,
136+ rt : runtime:: Handle ,
132137}
133138
134139impl < C > DocsClient < C >
@@ -138,7 +143,7 @@ where
138143 /// Create a new document.
139144 pub async fn create ( & self ) -> Result < Doc < C > > {
140145 let res = self . rpc . rpc ( DocCreateRequest { } ) . await ??;
141- let doc = Doc :: new ( self . rpc . clone ( ) , res. id ) ;
146+ let doc = Doc :: new ( self . rt . clone ( ) , self . rpc . clone ( ) , res. id ) ;
142147 Ok ( doc)
143148 }
144149
@@ -155,7 +160,7 @@ where
155160 /// Import a document from a ticket and join all peers in the ticket.
156161 pub async fn import ( & self , ticket : DocTicket ) -> Result < Doc < C > > {
157162 let res = self . rpc . rpc ( DocImportRequest ( ticket) ) . await ??;
158- let doc = Doc :: new ( self . rpc . clone ( ) , res. doc_id ) ;
163+ let doc = Doc :: new ( self . rt . clone ( ) , self . rpc . clone ( ) , res. doc_id ) ;
159164 Ok ( doc)
160165 }
161166
@@ -168,7 +173,7 @@ where
168173 /// Get a [`Doc`] client for a single document. Return None if the document cannot be found.
169174 pub async fn open ( & self , id : NamespaceId ) -> Result < Option < Doc < C > > > {
170175 self . rpc . rpc ( DocOpenRequest { doc_id : id } ) . await ??;
171- let doc = Doc :: new ( self . rpc . clone ( ) , id) ;
176+ let doc = Doc :: new ( self . rt . clone ( ) , self . rpc . clone ( ) , id) ;
172177 Ok ( Some ( doc) )
173178 }
174179}
@@ -523,6 +528,7 @@ struct DocInner<C: ServiceConnection<ProviderService>> {
523528 id : NamespaceId ,
524529 rpc : RpcClient < ProviderService , C > ,
525530 closed : AtomicBool ,
531+ rt : runtime:: Handle ,
526532}
527533
528534impl < C > Drop for DocInner < C >
@@ -532,7 +538,7 @@ where
532538 fn drop ( & mut self ) {
533539 let doc_id = self . id ;
534540 let rpc = self . rpc . clone ( ) ;
535- tokio :: task :: spawn ( async move {
541+ self . rt . main ( ) . spawn ( async move {
536542 rpc. rpc ( DocCloseRequest { doc_id } ) . await . ok ( ) ;
537543 } ) ;
538544 }
@@ -542,11 +548,12 @@ impl<C> Doc<C>
542548where
543549 C : ServiceConnection < ProviderService > ,
544550{
545- fn new ( rpc : RpcClient < ProviderService , C > , id : NamespaceId ) -> Self {
551+ fn new ( rt : runtime :: Handle , rpc : RpcClient < ProviderService , C > , id : NamespaceId ) -> Self {
546552 Self ( Arc :: new ( DocInner {
547553 rpc,
548554 id,
549555 closed : AtomicBool :: new ( false ) ,
556+ rt,
550557 } ) )
551558 }
552559
@@ -741,3 +748,35 @@ where
741748 Err ( err) => Err ( err. into ( ) ) ,
742749 } )
743750}
751+
752+ #[ cfg( test) ]
753+ mod tests {
754+ use super :: * ;
755+
756+ use iroh_bytes:: util:: runtime;
757+
758+ #[ tokio:: test]
759+ async fn test_drop_doc_client_sync ( ) -> Result < ( ) > {
760+ let db = iroh_bytes:: store:: readonly_mem:: Store :: default ( ) ;
761+ let doc_store = iroh_sync:: store:: memory:: Store :: default ( ) ;
762+ let rt = runtime:: Handle :: from_current ( 1 ) ?;
763+ let node = crate :: node:: Node :: builder ( db, doc_store)
764+ . runtime ( & rt)
765+ . spawn ( )
766+ . await ?;
767+
768+ let client = node. client ( ) ;
769+ let doc = client. docs . create ( ) . await ?;
770+
771+ let res = std:: thread:: spawn ( move || {
772+ drop ( doc) ;
773+ drop ( client) ;
774+ drop ( node) ;
775+ } ) ;
776+
777+ tokio:: task:: spawn_blocking ( move || res. join ( ) . map_err ( |e| anyhow:: anyhow!( "{:?}" , e) ) )
778+ . await ??;
779+
780+ Ok ( ( ) )
781+ }
782+ }
0 commit comments