@@ -7,10 +7,11 @@ mod watch;
77mod xid;
88
99use std:: pin:: pin;
10+ use std:: sync:: Weak ;
1011use std:: time:: { Duration , Instant } ;
1112
1213use async_io:: Timer ;
13- use asyncs:: select;
14+ use asyncs:: { select, sync } ;
1415use futures:: channel:: mpsc;
1516use futures:: { AsyncWriteExt , StreamExt } ;
1617use ignore_result:: Ignore ;
@@ -25,13 +26,13 @@ pub use self::request::{
2526 MarshalledRequest ,
2627 OpStat ,
2728 Operation ,
29+ Request ,
2830 SessionOperation ,
2931 StateReceiver ,
30- StateResponser ,
3132} ;
3233pub use self :: types:: { EventType , SessionId , SessionInfo , SessionState , WatchedEvent } ;
34+ use self :: watch:: WatchManager ;
3335pub use self :: watch:: { OneshotReceiver , PersistentReceiver , WatchReceiver } ;
34- use self :: watch:: { WatchManager , WatcherId } ;
3536use crate :: deadline:: Deadline ;
3637use crate :: endpoint:: IterableEndpoints ;
3738use crate :: error:: Error ;
@@ -45,22 +46,6 @@ use crate::tls::TlsOptions;
4546pub const PASSWORD_LEN : usize = 16 ;
4647pub const DEFAULT_SESSION_TIMEOUT : Duration = Duration :: from_secs ( 6 ) ;
4748
48- trait RequestOperation {
49- fn into_responser ( self ) -> StateResponser ;
50- }
51-
52- impl RequestOperation for SessionOperation {
53- fn into_responser ( self ) -> StateResponser {
54- self . responser
55- }
56- }
57-
58- impl RequestOperation for ( WatcherId , StateResponser ) {
59- fn into_responser ( self ) -> StateResponser {
60- self . 1
61- }
62- }
63-
6449#[ derive( Default ) ]
6550pub struct Builder {
6651 #[ cfg( feature = "tls" ) ]
@@ -110,7 +95,7 @@ impl Builder {
11095 Self { connection_timeout, ..self }
11196 }
11297
113- pub fn build ( self ) -> Result < ( Session , asyncs :: sync :: watch :: Receiver < SessionState > ) , Error > {
98+ pub fn build ( self , requester : Weak < mpsc :: UnboundedSender < Request > > ) -> Result < Session , Error > {
11499 let session = match self . session {
115100 Some ( session) => {
116101 if session. is_readonly ( ) {
@@ -136,9 +121,9 @@ impl Builder {
136121 } ;
137122 #[ cfg( not( feature = "tls" ) ) ]
138123 let connector = Connector :: new ( ) ;
139- let ( state_sender, state_receiver) = asyncs :: sync:: watch:: channel ( SessionState :: Disconnected ) ;
124+ let ( state_sender, state_receiver) = sync:: watch:: channel ( SessionState :: Disconnected ) ;
140125 let now = Instant :: now ( ) ;
141- let ( watch_manager, unwatch_receiver ) = WatchManager :: new ( ) ;
126+ let watch_manager = WatchManager :: new ( requester , state_receiver ) ;
142127 let mut session = Session {
143128 readonly : self . readonly ,
144129 detached : self . detached ,
@@ -165,11 +150,10 @@ impl Builder {
165150 authes : self . authes ,
166151 state_sender,
167152 watch_manager,
168- unwatch_receiver : Some ( unwatch_receiver) ,
169153 } ;
170154 let timeout = if self . session_timeout . is_zero ( ) { DEFAULT_SESSION_TIMEOUT } else { self . session_timeout } ;
171155 session. reset_timeout ( timeout) ;
172- Ok ( ( session, state_receiver ) )
156+ Ok ( session)
173157 }
174158}
175159
@@ -199,10 +183,9 @@ pub struct Session {
199183 sasl_session : Option < SaslSession > ,
200184
201185 pub authes : Vec < MarshalledRequest > ,
202- state_sender : asyncs :: sync:: watch:: Sender < SessionState > ,
186+ state_sender : sync:: watch:: Sender < SessionState > ,
203187
204188 watch_manager : WatchManager ,
205- unwatch_receiver : Option < mpsc:: UnboundedReceiver < ( WatcherId , StateResponser ) > > ,
206189}
207190
208191impl Session {
@@ -215,27 +198,30 @@ impl Session {
215198 self . readonly && self . session . readonly
216199 }
217200
218- async fn close_requester < T : RequestOperation > ( mut requester : mpsc:: UnboundedReceiver < T > , err : & Error ) {
201+ async fn close_requester ( mut requester : mpsc:: UnboundedReceiver < Request > , err : & Error ) {
219202 requester. close ( ) ;
220- while let Some ( operation ) = requester. next ( ) . await {
221- let responser = operation . into_responser ( ) ;
203+ while let Some ( request ) = requester. next ( ) . await {
204+ let responser = request . into_responser ( ) ;
222205 responser. send ( Err ( err. clone ( ) ) ) ;
223206 }
224207 }
225208
209+ pub fn subscribe_state ( & self ) -> sync:: watch:: Receiver < SessionState > {
210+ self . state_sender . subscribe ( )
211+ }
212+
226213 #[ instrument( name = "serve" , skip_all, fields( session = display( self . session. id) ) ) ]
227214 pub async fn serve (
228215 & mut self ,
229216 mut endpoints : IterableEndpoints ,
230217 conn : Connection ,
231218 mut buf : Vec < u8 > ,
232219 mut depot : Depot ,
233- mut requester : mpsc:: UnboundedReceiver < SessionOperation > ,
220+ mut requester : mpsc:: UnboundedReceiver < Request > ,
234221 ) {
235- let mut unwatch_requester = self . unwatch_receiver . take ( ) . unwrap ( ) ;
236222 endpoints. cycle ( ) ;
237223 endpoints. reset ( ) ;
238- self . serve_once ( conn, & mut endpoints, & mut buf, & mut depot, & mut requester, & mut unwatch_requester ) . await ;
224+ self . serve_once ( conn, & mut endpoints, & mut buf, & mut depot, & mut requester) . await ;
239225 while !self . session_state . is_terminated ( ) {
240226 let conn = match self . start ( & mut endpoints, & mut buf, & mut depot) . await {
241227 Err ( err) => {
@@ -246,11 +232,10 @@ impl Session {
246232 Ok ( conn) => conn,
247233 } ;
248234 endpoints. reset ( ) ;
249- self . serve_once ( conn, & mut endpoints, & mut buf, & mut depot, & mut requester, & mut unwatch_requester ) . await ;
235+ self . serve_once ( conn, & mut endpoints, & mut buf, & mut depot, & mut requester) . await ;
250236 }
251237 let err = self . state_error ( ) ;
252238 Self :: close_requester ( requester, & err) . await ;
253- Self :: close_requester ( unwatch_requester, & err) . await ;
254239 depot. terminate ( err) ;
255240 }
256241
@@ -292,10 +277,9 @@ impl Session {
292277 endpoints : & mut IterableEndpoints ,
293278 buf : & mut Vec < u8 > ,
294279 depot : & mut Depot ,
295- requester : & mut mpsc:: UnboundedReceiver < SessionOperation > ,
296- unwatch_requester : & mut mpsc:: UnboundedReceiver < ( WatcherId , StateResponser ) > ,
280+ requester : & mut mpsc:: UnboundedReceiver < Request > ,
297281 ) {
298- let err = self . serve_session ( endpoints, & mut conn, buf, depot, requester, unwatch_requester ) . await . unwrap_err ( ) ;
282+ let err = self . serve_session ( endpoints, & mut conn, buf, depot, requester) . await . unwrap_err ( ) ;
299283 self . resolve_serve_error ( & err) ;
300284 info ! ( "enter state {} due to {}" , self . session_state, err) ;
301285 depot. error ( & err) ;
@@ -550,8 +534,7 @@ impl Session {
550534 conn : & mut Connection ,
551535 buf : & mut Vec < u8 > ,
552536 depot : & mut Depot ,
553- requester : & mut mpsc:: UnboundedReceiver < SessionOperation > ,
554- unwatch_requester : & mut mpsc:: UnboundedReceiver < ( WatcherId , StateResponser ) > ,
537+ requester : & mut mpsc:: UnboundedReceiver < Request > ,
555538 ) -> Result < ( ) , Error > {
556539 #[ cfg( any( feature = "sasl-digest-md5" , feature = "sasl-gssapi" ) ) ]
557540 self . sasl_session . take ( ) ;
@@ -577,20 +560,19 @@ impl Session {
577560 r?;
578561 self . last_send = Instant :: now( ) ;
579562 } ,
580- r = requester. next( ) , if !channel_halted => {
581- let operation = if let Some ( operation) = r {
582- operation
583- } else {
563+ r = requester. next( ) , if !channel_halted => match r {
564+ None => {
584565 if !self . detached {
585566 depot. push_session( SessionOperation :: new_without_body( OpCode :: CloseSession ) ) ;
586567 }
587568 channel_halted = true ;
588- continue ;
589- } ;
590- depot. push_session( operation) ;
591- } ,
592- r = unwatch_requester. next( ) => if let Some ( ( watcher_id, responser) ) = r {
593- self . watch_manager. remove_watcher( watcher_id, responser, depot) ;
569+ }
570+ Some ( Request :: Session ( operation) ) => depot. push_session( operation) ,
571+ Some ( Request :: RemoveWatcher {
572+ id, responser
573+ } ) => {
574+ self . watch_manager. remove_watcher( id, responser, depot) ;
575+ }
594576 } ,
595577 now = tick. as_mut( ) => {
596578 if now >= self . last_recv + self . connector. timeout( ) {
0 commit comments