@@ -6,7 +6,7 @@ use std::sync::Arc;
6
6
use tokio_service:: { self , Service as TokioService } ;
7
7
use jsonrpc:: futures:: { future, Future , Stream , Sink } ;
8
8
use jsonrpc:: futures:: sync:: { mpsc, oneshot} ;
9
- use jsonrpc:: { FutureResult , Metadata , MetaIoHandler , Middleware , NoopMiddleware } ;
9
+ use jsonrpc:: { Metadata , MetaIoHandler , Middleware , NoopMiddleware } ;
10
10
use server_utils:: {
11
11
tokio_codec:: Framed ,
12
12
tokio:: { self , runtime:: TaskExecutor , reactor:: Handle } ,
@@ -36,13 +36,25 @@ impl<M: Metadata, S: Middleware<M>> tokio_service::Service for Service<M, S> {
36
36
type Request = String ;
37
37
type Response = Option < String > ;
38
38
39
- type Error = ( ) ;
39
+ type Error = std :: io :: Error ;
40
40
41
- type Future = FutureResult < S :: Future > ;
41
+ type Future = Box < Future < Item = Self :: Response , Error = Self :: Error > + Send > ;
42
42
43
43
fn call ( & self , req : Self :: Request ) -> Self :: Future {
44
44
trace ! ( target: "ipc" , "Received request: {}" , req) ;
45
- self . handler . handle_request ( & req, self . meta . clone ( ) )
45
+ let fut = self . handler
46
+ . handle_request ( & req, self . meta . clone ( ) )
47
+ . then ( |result| {
48
+ match result {
49
+ Err ( _) => {
50
+ future:: ok ( None )
51
+ }
52
+ Ok ( some_result) => future:: ok ( some_result) ,
53
+ }
54
+ } )
55
+ . map_err ( |_: ( ) | std:: io:: ErrorKind :: Other . into ( ) ) ;
56
+
57
+ Box :: new ( fut)
46
58
}
47
59
}
48
60
@@ -55,6 +67,7 @@ pub struct ServerBuilder<M: Metadata = (), S: Middleware<M> = NoopMiddleware> {
55
67
incoming_separator : codecs:: Separator ,
56
68
outgoing_separator : codecs:: Separator ,
57
69
security_attributes : SecurityAttributes ,
70
+ client_buffer_size : usize ,
58
71
}
59
72
60
73
impl < M : Metadata + Default , S : Middleware < M > > ServerBuilder < M , S > {
@@ -80,6 +93,7 @@ impl<M: Metadata, S: Middleware<M>> ServerBuilder<M, S> {
80
93
incoming_separator : codecs:: Separator :: Empty ,
81
94
outgoing_separator : codecs:: Separator :: default ( ) ,
82
95
security_attributes : SecurityAttributes :: empty ( ) ,
96
+ client_buffer_size : 5 ,
83
97
}
84
98
}
85
99
@@ -116,6 +130,12 @@ impl<M: Metadata, S: Middleware<M>> ServerBuilder<M, S> {
116
130
self
117
131
}
118
132
133
+ /// Sets how many concurrent requests per client can be processed at any one time. Set to 5 by default.
134
+ pub fn set_client_buffer_size ( mut self , buffer_size : usize ) -> Self {
135
+ self . client_buffer_size = buffer_size;
136
+ self
137
+ }
138
+
119
139
/// Creates a new server from the given endpoint.
120
140
pub fn start ( self , path : & str ) -> std:: io:: Result < Server > {
121
141
let executor = self . executor . initialize ( ) ?;
@@ -129,6 +149,7 @@ impl<M: Metadata, S: Middleware<M>> ServerBuilder<M, S> {
129
149
let ( start_signal, start_receiver) = oneshot:: channel ( ) ;
130
150
let ( wait_signal, wait_receiver) = oneshot:: channel ( ) ;
131
151
let security_attributes = self . security_attributes ;
152
+ let client_buffer_size = self . client_buffer_size ;
132
153
133
154
executor. spawn ( future:: lazy ( move || {
134
155
let mut endpoint = Endpoint :: new ( endpoint_addr) ;
@@ -173,27 +194,17 @@ impl<M: Metadata, S: Middleware<M>> ServerBuilder<M, S> {
173
194
outgoing_separator. clone ( ) ,
174
195
) ,
175
196
) . split ( ) ;
176
- let responses = reader. and_then ( move |req| {
177
- service. call ( req) . then ( move |response| match response {
178
- Err ( e) => {
179
- warn ! ( target: "ipc" , "Error while processing request: {:?}" , e) ;
180
- future:: ok ( None )
181
- } ,
182
- Ok ( None ) => {
183
- future:: ok ( None )
184
- } ,
185
- Ok ( Some ( response_data) ) => {
186
- trace ! ( target: "ipc" , "Sent response: {}" , & response_data) ;
187
- future:: ok ( Some ( response_data) )
188
- }
197
+ let responses = reader
198
+ . map ( move |req| {
199
+ service. call ( req)
189
200
} )
190
- } )
191
- . filter_map ( |x| x)
192
- // we use `select_with_weak` here, instead of `select`, to close the stream
193
- // as soon as the ipc pipe is closed
194
- . select_with_weak ( receiver. map_err ( |e| {
195
- warn ! ( target: "ipc" , "Notification error: {:?}" , e) ;
196
- std:: io:: ErrorKind :: Other . into ( )
201
+ . buffer_unordered ( client_buffer_size )
202
+ . filter_map ( |x| x)
203
+ // we use `select_with_weak` here, instead of `select`, to close the stream
204
+ // as soon as the ipc pipe is closed
205
+ . select_with_weak ( receiver. map_err ( |e| {
206
+ warn ! ( target: "ipc" , "Notification error: {:?}" , e) ;
207
+ std:: io:: ErrorKind :: Other . into ( )
197
208
} ) ) ;
198
209
199
210
let writer = writer. send_all ( responses) . then ( move |_| {
0 commit comments