- Notifications
You must be signed in to change notification settings - Fork515
Description
Hey,
I'm not sure whether to be impressed or scared. My application (using tokio-postgres) started producing ~125k errors per second (and incurred $800 of AWS CloudWatch Logs costs). The specific error was:
connection error: error communicating with the server: Socket not connected (os error 107)
This is coming from here:
asyncfncreate_client(config:&tokio_postgres::Config) ->Result<tokio_postgres::Client, tokio_postgres::Error>{letmut config = config.clone(); config.connect_timeout(Duration::from_secs(5));// default is no timeoutlet(client,mut connection) = config.connect(make_tls()).await?; tokio::spawn(asyncmove{letmut messages = futures::stream::poll_fn(move |cx| connection.poll_message(cx));loop{match messages.next().await{Some(Ok(AsyncMessage::Notice(notice))) =>{ tracing::debug!("connection notice: {}", notice);}Some(Ok(_)) =>{}Some(Err(error)) =>{ tracing::error!("connection error: {}", error);}None =>break}}});Ok(client)}
I suspect the reason is thatpoll_message
callspoll_shutdown
, which callsFramed/Sink::poll_close
, which returnsErr
. According to the documentation ofSink
, "If this function encounters an error, the sink should be considered to have failed permanently, and no more Sink methods should be called.", however, tokio-postgres does not remember this and keeps calling it.
Or perhaps this is expected and I should stop reading afterErr
is returned, in which case it would be nice to explicitly document this. Because of theOption
and the semantics of a stream, I assumed the interface wasStream
-y and terminates afterNone
is returned.