4
4
* Copyright (c) storycraft. Licensed under the MIT Licence.
5
5
*/
6
6
7
- use std:: { collections :: VecDeque , io:: { self , Read , Write } , time:: Duration } ;
7
+ use std:: { io:: { self , Read , Write } , time:: Duration , vec :: Drain } ;
8
8
9
9
use bson:: Document ;
10
10
use loco_protocol:: command:: codec:: StreamError ;
@@ -36,26 +36,26 @@ impl From<ReadError> for RequestError {
36
36
/// Command session with command cache.
37
37
/// Provide methods for requesting command response and broadcast command handling.
38
38
/// Useful when creating client.
39
- /// You must use non blocking mode to prevent blocking. Also using async is recommended .
39
+ /// Using non blocking mode highly recommended to prevent blocking.
40
40
#[ derive( Debug ) ]
41
41
pub struct BsonCommandSession < S > {
42
- store : VecDeque < BsonCommand < Document > > ,
42
+ store : Vec < BsonCommand < Document > > ,
43
43
manager : BsonCommandManager < S > ,
44
44
}
45
45
46
46
impl < S > BsonCommandSession < S > {
47
47
/// Create new [BsonCommandSession]
48
48
pub fn new ( stream : S ) -> Self {
49
49
Self {
50
- store : VecDeque :: new ( ) ,
50
+ store : Vec :: new ( ) ,
51
51
manager : BsonCommandManager :: new ( stream) ,
52
52
}
53
53
}
54
54
55
55
/// Create new [BsonCommandSession] with specific max write chunk size.
56
56
pub fn with_capacity ( stream : S , max_write_chunk_size : usize ) -> Self {
57
57
Self {
58
- store : VecDeque :: new ( ) ,
58
+ store : Vec :: new ( ) ,
59
59
manager : BsonCommandManager :: with_capacity ( stream, max_write_chunk_size) ,
60
60
}
61
61
}
@@ -93,14 +93,15 @@ impl<S: Read + Write> BsonCommandSession<S> {
93
93
if id == request_id && read. method == command. method {
94
94
return Ok ( read. data ) ;
95
95
} else {
96
- self . store . push_back ( read) ;
96
+ self . store . push ( read) ;
97
97
}
98
98
}
99
99
100
100
Err ( ReadError :: Codec ( StreamError :: Io ( err) ) )
101
- if err. kind ( ) == io:: ErrorKind :: WouldBlock => {
102
- std:: thread:: sleep ( Duration :: from_millis ( 1 ) ) ;
103
- }
101
+ if err. kind ( ) == io:: ErrorKind :: WouldBlock =>
102
+ {
103
+ std:: thread:: sleep ( Duration :: from_millis ( 1 ) ) ;
104
+ }
104
105
105
106
Err ( err) => return Err ( RequestError :: from ( err) ) ,
106
107
}
@@ -109,22 +110,35 @@ impl<S: Read + Write> BsonCommandSession<S> {
109
110
}
110
111
111
112
impl < S : Read > BsonCommandSession < S > {
112
- /// Poll next broadcast command.
113
- pub fn poll_broadcast ( & mut self ) -> Result < Option < BsonCommand < Document > > , ReadError > {
114
- match self . store . pop_front ( ) {
115
- Some ( command) => Ok ( Some ( command) ) ,
116
-
117
- None => match self . manager . read ( ) {
118
- Ok ( ( _, read) ) => Ok ( Some ( read) ) ,
113
+ /// Poll one broadcast command.
114
+ /// This method can block depending on stream.
115
+ pub fn poll ( & mut self ) -> Result < ( ) , ReadError > {
116
+ self . poll_many ( 1 )
117
+ }
119
118
119
+ /// Poll broadcast commands up to max limit
120
+ pub fn poll_many ( & mut self , max : usize ) -> Result < ( ) , ReadError > {
121
+ for _ in 0 ..max {
122
+ match self . manager . read ( ) {
123
+ Ok ( ( _, read) ) => {
124
+ self . store . push ( read)
125
+ } ,
126
+
120
127
Err ( ReadError :: Codec ( StreamError :: Io ( err) ) )
121
128
if err. kind ( ) == io:: ErrorKind :: WouldBlock =>
122
129
{
123
- Ok ( None )
130
+ break ;
124
131
}
125
-
126
- Err ( err) => Err ( ReadError :: from ( err) ) ,
132
+
133
+ Err ( err) => return Err ( ReadError :: from ( err) ) ,
127
134
}
128
135
}
136
+
137
+ Ok ( ( ) )
138
+ }
139
+
140
+ /// Drain every broadcast commands stored
141
+ pub fn broadcasts ( & mut self ) -> Drain < ' _ , BsonCommand < Document > > {
142
+ self . store . drain ( ..)
129
143
}
130
144
}
0 commit comments