Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e9db2bf

Browse files
committed
Defer message sends until first poll
This matches up generally with the "futures do nothing until polled" model.
1 parent 9d5a36e commit e9db2bf

File tree

6 files changed

+35
-53
lines changed

6 files changed

+35
-53
lines changed

tokio-postgres/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ tokio-codec = "0.1"
4545
tokio-io = "0.1"
4646
tokio-tcp = "0.1"
4747
tokio-timer = "0.2"
48-
want = "0.0.5"
4948

5049
[target.'cfg(unix)'.dependencies]
5150
tokio-uds = "0.2"

tokio-postgres/src/lib.rs

-11
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ extern crate tokio_codec;
77
extern crate tokio_io;
88
extern crate tokio_tcp;
99
extern crate tokio_timer;
10-
extern crate want;
1110

1211
#[macro_use]
1312
extern crate futures;
@@ -61,16 +60,6 @@ pub fn connect(params: ConnectParams) -> Handshake {
6160
pub struct Client(proto::Client);
6261

6362
impl Client {
64-
/// Polls to to determine whether the connection is ready to send new requests to the backend.
65-
///
66-
/// Requests are unboundedly buffered to enable pipelining, but this risks unbounded memory consumption if requests
67-
/// are produced at a faster pace than the backend can process. This method can be used to cooperatively "throttle"
68-
/// request creation. Specifically, it returns ready when the connection has sent any queued requests and is waiting
69-
/// on new requests from the client.
70-
pub fn poll_ready(&mut self) -> Poll<(), Error> {
71-
self.0.poll_ready()
72-
}
73-
7463
pub fn prepare(&mut self, query: &str) -> Prepare {
7564
self.prepare_typed(query, &[])
7665
}

tokio-postgres/src/proto/client.rs

+27-22
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,51 @@
11
use futures::sync::mpsc;
2-
use futures::Poll;
32
use postgres_protocol::message::backend::Message;
43
use postgres_protocol::message::frontend;
5-
use want::Giver;
64

75
use disconnected;
86
use error::Error;
97
use proto::connection::Request;
108
use proto::prepare::PrepareFuture;
119
use types::Type;
1210

13-
pub struct Client {
11+
pub struct PendingRequest {
1412
sender: mpsc::UnboundedSender<Request>,
15-
giver: Giver,
13+
messages: Vec<u8>,
1614
}
1715

18-
impl Client {
19-
pub fn new(sender: mpsc::UnboundedSender<Request>, giver: Giver) -> Client {
20-
Client { sender, giver }
16+
impl PendingRequest {
17+
pub fn send(self) -> Result<mpsc::Receiver<Message>, Error> {
18+
let (sender, receiver) = mpsc::channel(0);
19+
self.sender
20+
.unbounded_send(Request {
21+
messages: self.messages,
22+
sender,
23+
})
24+
.map(|_| receiver)
25+
.map_err(|_| disconnected())
2126
}
27+
}
28+
29+
pub struct Client {
30+
sender: mpsc::UnboundedSender<Request>,
31+
}
2232

23-
pub fn poll_ready(&mut self) -> Poll<(), Error> {
24-
self.giver.poll_want().map_err(|_| disconnected())
33+
impl Client {
34+
pub fn new(sender: mpsc::UnboundedSender<Request>) -> Client {
35+
Client { sender }
2536
}
2637

2738
pub fn prepare(&mut self, name: String, query: &str, param_types: &[Type]) -> PrepareFuture {
2839
let mut buf = vec![];
29-
let receiver = frontend::parse(&name, query, param_types.iter().map(|t| t.oid()), &mut buf)
40+
let request = frontend::parse(&name, query, param_types.iter().map(|t| t.oid()), &mut buf)
3041
.and_then(|()| frontend::describe(b'S', &name, &mut buf))
3142
.and_then(|()| Ok(frontend::sync(&mut buf)))
32-
.map_err(Into::into)
33-
.and_then(|()| self.send(buf));
34-
35-
PrepareFuture::new(self.sender.clone(), receiver, name)
36-
}
43+
.map(|()| PendingRequest {
44+
sender: self.sender.clone(),
45+
messages: buf,
46+
})
47+
.map_err(Into::into);
3748

38-
fn send(&mut self, messages: Vec<u8>) -> Result<mpsc::Receiver<Message>, Error> {
39-
let (sender, receiver) = mpsc::channel(0);
40-
self.giver.give();
41-
self.sender
42-
.unbounded_send(Request { messages, sender })
43-
.map(|_| receiver)
44-
.map_err(|_| disconnected())
49+
PrepareFuture::new(request, self.sender.clone(), name)
4550
}
4651
}

tokio-postgres/src/proto/connection.rs

-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use postgres_protocol::message::frontend;
55
use std::collections::{HashMap, VecDeque};
66
use std::io;
77
use tokio_codec::Framed;
8-
use want::Taker;
98

109
use disconnected;
1110
use error::{self, Error};
@@ -30,7 +29,6 @@ pub struct Connection {
3029
cancel_data: CancelData,
3130
parameters: HashMap<String, String>,
3231
receiver: mpsc::UnboundedReceiver<Request>,
33-
taker: Taker,
3432
pending_request: Option<Vec<u8>>,
3533
pending_response: Option<Message>,
3634
responses: VecDeque<mpsc::Sender<Message>>,
@@ -43,14 +41,12 @@ impl Connection {
4341
cancel_data: CancelData,
4442
parameters: HashMap<String, String>,
4543
receiver: mpsc::UnboundedReceiver<Request>,
46-
taker: Taker,
4744
) -> Connection {
4845
Connection {
4946
stream,
5047
cancel_data,
5148
parameters,
5249
receiver,
53-
taker,
5450
pending_request: None,
5551
pending_response: None,
5652
responses: VecDeque::new(),
@@ -178,7 +174,6 @@ impl Connection {
178174
}
179175
Async::NotReady => {
180176
trace!("poll_write: waiting on request");
181-
self.taker.want();
182177
return Ok(true);
183178
}
184179
};

tokio-postgres/src/proto/handshake.rs

+3-10
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use state_machine_future::RentToOwn;
1010
use std::collections::HashMap;
1111
use std::io;
1212
use tokio_codec::Framed;
13-
use want;
1413

1514
use error::{self, Error};
1615
use params::{ConnectParams, User};
@@ -284,15 +283,9 @@ impl PollHandshake for Handshake {
284283
io::Error::new(io::ErrorKind::InvalidData, "BackendKeyData message missing")
285284
})?;
286285
let (sender, receiver) = mpsc::unbounded();
287-
let (giver, taker) = want::new();
288-
let client = Client::new(sender, giver);
289-
let connection = Connection::new(
290-
state.stream,
291-
cancel_data,
292-
state.parameters,
293-
receiver,
294-
taker,
295-
);
286+
let client = Client::new(sender);
287+
let connection =
288+
Connection::new(state.stream, cancel_data, state.parameters, receiver);
296289
transition!(Finished((client, connection)))
297290
}
298291
Some(Message::ErrorResponse(body)) => return Err(error::__db(body)),

tokio-postgres/src/proto/prepare.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use postgres_protocol::message::backend::{Message, ParameterDescriptionBody, Row
55
use state_machine_future::RentToOwn;
66

77
use error::{self, Error};
8+
use proto::client::PendingRequest;
89
use proto::connection::Request;
910
use proto::statement::Statement;
1011
use types::Type;
@@ -15,8 +16,8 @@ use {bad_response, disconnected};
1516
pub enum Prepare {
1617
#[state_machine_future(start, transitions(ReadParseComplete))]
1718
Start {
19+
request: Result<PendingRequest, Error>,
1820
sender: mpsc::UnboundedSender<Request>,
19-
receiver: Result<mpsc::Receiver<Message>, Error>,
2021
name: String,
2122
},
2223
#[state_machine_future(transitions(ReadParameterDescription))]
@@ -55,7 +56,7 @@ pub enum Prepare {
5556
impl PollPrepare for Prepare {
5657
fn poll_start<'a>(state: &'a mut RentToOwn<'a, Start>) -> Poll<AfterStart, Error> {
5758
let state = state.take();
58-
let receiver = state.receiver?;
59+
let receiver = state.request?.send()?;
5960

6061
transition!(ReadParseComplete {
6162
sender: state.sender,
@@ -159,10 +160,10 @@ impl PollPrepare for Prepare {
159160

160161
impl PrepareFuture {
161162
pub fn new(
163+
request: Result<PendingRequest, Error>,
162164
sender: mpsc::UnboundedSender<Request>,
163-
receiver: Result<mpsc::Receiver<Message>, Error>,
164165
name: String,
165166
) -> PrepareFuture {
166-
Prepare::start(sender, receiver, name)
167+
Prepare::start(request, sender, name)
167168
}
168169
}

0 commit comments

Comments
 (0)