tls.Conn and SetWriteDeadline

372 views
Skip to first unread message

Jason Woods

unread,
May 21, 2014, 11:39:40 AM5/21/14
to golan...@googlegroups.com
Hi all,

I'm trying to use SetWriteDeadline on tls.Conn, so I can check a shutdown signal every few seconds, but keep data flowing through as fast as possible.
Unfortunately, it appears that once tls.Conn.Write() fails with a timeout error due to deadline, it cannot be retries and will permanently call. My other goroutine that calls Read also then permanently fails.

It seems you can only recover from deadline on tls.Conn.Read() and not tls.Conn.Write() after checking the source. I guess the reason is that tls.Conn.Read() doesn't process until it reads a full buffer, so subsequent calls it keeps trying to fill that buffer. However, write creates the message and attempts to send, and if deadline hit during that it ignores how much was written and never tries again, failing completely.

So. Is tls.Conn.Write() supposed to allow retry with deadline? Or do I need to find another approach to shutdown - any ideas what that might involve?

Thanks!

go version go1.2.1 darwin/amd64

Jason

Mikio Hara

unread,
May 21, 2014, 9:07:18 PM5/21/14
to Jason Woods, golang-nuts
yup, you need to take another approach. fyi:
http://golang.org/pkg/crypto/tls/#Conn.SetWriteDeadline.
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Jesse McNelis

unread,
May 21, 2014, 9:16:37 PM5/21/14
to Jason Woods, golang-nuts
On Thu, May 22, 2014 at 1:39 AM, Jason Woods <de...@jasonwoods.me.uk> wrote:
> So. Is tls.Conn.Write() supposed to allow retry with deadline? Or do I need
> to find another approach to shutdown - any ideas what that might involve?

It's the traditional meaning of 'deadline' not the business meaning of
'deadline'.
Why have a deadline if you're just going to try again?

Jason Woods

unread,
May 22, 2014, 1:52:10 AM5/22/14
to golan...@googlegroups.com
Hi
The error returned is marked "Temporary". Maybe it should be changed so it's not.
Not sure what you mean by "meaning of deadline" though as I only know one meaning. I just wanted to extend the deadline, which was a temporary failure, so to speak.

Pretty sure I read the docs but never saw it mention! Haha. Thanks.

I've worked around it though by moving my shutdown check into a net.Conn wrapper and passing that into tls.Client - on shutdown I simply return the timeout with Temporary set false, otherwise retry.

Thanks

Jason

Gyepi SAM

unread,
May 22, 2014, 2:15:04 AM5/22/14
to Jason Woods, golan...@googlegroups.com
On Thu, May 22, 2014 at 06:52:10AM +0100, Jason Woods wrote:
> > It's the traditional meaning of 'deadline' not the business meaning of
> > 'deadline'.
> > Why have a deadline if you're just going to try again?
>
> The error returned is marked "Temporary". Maybe it should be changed so it's not.
> Not sure what you mean by "meaning of deadline" though as I only know one meaning. I just wanted to extend the deadline, which was a temporary failure, so to speak.

The traditional meaning is rooted in American history, likely Civil War, but
could be earlier: a line beyond which prisoners in a stockade may not cross
upon penalty of being shot.

Apparently, newspaper printers started using the term to denote physical boundaries on a
page and the term soon percolated into the newsroom from whence it emerged
with a new, and now generally accepted, meaning.

-Gyepi

Mikio Hara

unread,
May 22, 2014, 2:53:25 AM5/22/14
to Jason Woods, golan...@googlegroups.com
On Thu, May 22, 2014 at 2:52 PM, Jason Woods <de...@jasonwoods.me.uk> wrote:

> The error returned is marked "Temporary". Maybe it should be changed so it's not.

filed, golang.org/issue/8071.

Jason Woods

unread,
May 22, 2014, 3:08:36 AM5/22/14
to golan...@googlegroups.com
Oh thanks! Guess I could have done myself instead of asking ! Sorry!

Jason

Jesse McNelis

unread,
May 22, 2014, 3:17:42 AM5/22/14
to Jason Woods, golan...@googlegroups.com
On Thu, May 22, 2014 at 3:52 PM, Jason Woods <de...@jasonwoods.me.uk> wrote:
> Not sure what you mean by "meaning of deadline" though as I only know one meaning. I just wanted to extend the deadline, which was a temporary failure, so to speak.

A deadline generally has some reason for it's existence. eg. "we need
to get food by the end of the month or we'll die".
More recently in project management it's an arbitrarily chosen time in
the future as a goal to work towards which can be arbitrarily extended
because it not based on any actual reasons.

The reason for a network connection to have a deadline is to prevent a
slow/malicious client from tying up server resources.
Extending the deadline just allows this slow/malicious client to keep
tying up resources.

So, why have a deadline if you're just going to extend it, why no just
make the deadline further in to the future in the first place?

Jason Woods

unread,
May 22, 2014, 4:15:42 AM5/22/14
to golan...@googlegroups.com
Hi,
I don't understand your point. Deadlines in go always result in a timeout that is a temporary error, and it can always be extended on the lower level sockets. Regardless of semantics of the word "deadline", the meaning of a deadline within go is already specified by its functionality on lower level sockets.

If you mean Go should change the word "deadline" to something else, because its American English / British English meaning does not reflect its functionality, then I'm not sure this is the right topic for that.

To elaborate on my original problem, it was that the deadline functionality in the higher level TLS socket, and only on Write(), did not reflect that of the lower level sockets. I can now see that it is documented as such. The only real probably issue is that it returns it in the same way as the lower level sockets, i.e., a net.Error implementation where Timeout() returns true and Temporary() returns true. At this level, and because the TLS state becomes corrupt, probably it should be Timeout() true and Temporary() false.

Let's not dwell on the meaning of a word and consider this purely in the context of Go and its implementation, which is an entirely unique language.

To elaborate on my requirements though, I simply need to send data to a processing endpoint as fast as possible, by filling send buffer till send blocks, and also shutdown cleanly on demand. The server receiving the data is allowed to be slow, so the send block can be a long time (minute or so) depending on time of day. The shutdown needs to be within 30 seconds as otherwise it is deemed hung and killed by service manager. Thus I needed deadline. I did solve the issue by doing the deadline in net.Conn wrapper which I passed to tls.Client, and this works perfectly.

Regards,

Jason
Reply all
Reply to author
Forward
0 new messages