Why SetDeadline and not SetTimeout?

1,249 views
Skip to first unread message

nfir...@nfirvine.com

unread,
Feb 3, 2016, 2:21:53 PM2/3/16
to golang-nuts
For Conns, they have a method SetDeadline(t time.Time). Why isn't this SetTimeout(d time.Duration) or something? Is there really a use case for deadlines in the past? Is it some limitation imposed by underlying platforms?

Roberto Zanotto

unread,
Feb 3, 2016, 2:42:08 PM2/3/16
to golang-nuts, nfir...@nfirvine.com
It was SetTimeout before 1.0, then it has been replaced by SetDeadline because SetTimeout gave problems and surprising results (with partial reads and writes, I suppose). I did read it here on nuts, can't find the post anymore.

Dave Cheney

unread,
Feb 3, 2016, 3:56:39 PM2/3/16
to golang-nuts, nfir...@nfirvine.com

Shawn Milochik

unread,
Feb 3, 2016, 3:58:58 PM2/3/16
to golang-nuts
On Wed, Feb 3, 2016 at 3:56 PM, Dave Cheney <da...@cheney.net> wrote:


Cool. Thanks for the info (and the original question). I've had to use this very recently and wondered about that myself. 

Nick Irvine

unread,
Feb 3, 2016, 7:58:11 PM2/3/16
to Dave Cheney, golang-nuts
Okay, good to know. But couldn't SetTimeout(d Duration) just be a call to SetDeadline(time.Now().Add(d))? SetDeadline just seems like an awkward API. Is there a semantic difference that I'm missing?

Jesse McNelis

unread,
Feb 3, 2016, 8:43:48 PM2/3/16
to Nick Irvine, golang-nuts
On Thu, Feb 4, 2016 at 11:57 AM, Nick Irvine <nfir...@nfirvine.com> wrote:
> Okay, good to know. But couldn't SetTimeout(d Duration) just be a call to
> SetDeadline(time.Now().Add(d))? SetDeadline just seems like an awkward API.
> Is there a semantic difference that I'm missing?
>

The semantic difference is that 'timeouts' generally refer to idle
time. ie. "wait this amount of time, if there isn't any activity then
timeout."
A 'deadline' refers to a time at which it should stop whether or not
it has activity.
Deadline is used here to protect against slowloris type attacks.
https://en.wikipedia.org/wiki/Slowloris_(computer_security)

SetDeadline() could have taken a Duration, but it reads weird. A
deadline usually refers to a specific time, not an amount of time from
now.

adon...@google.com

unread,
Feb 4, 2016, 9:57:53 AM2/4/16
to golang-nuts, nfir...@nfirvine.com, jes...@jessta.id.au
The advantage of a deadline is that its meaning is not relative to the start time.  That is, if task A starts subtask B, both can use the same deadline.  Had timeouts been used, A would have to subtract the amount of time elapsed between its start and its call to B, and the subroutine of A that starts B may not know what time A started.

Nick Irvine

unread,
Feb 4, 2016, 1:16:33 PM2/4/16
to golang-nuts
The semantic difference is that 'timeouts' generally refer to idle
time. ie. "wait this amount of time, if there isn't any activity then
timeout."
A 'deadline' refers to a time at which it should stop whether or not
it has activity.
Deadline is used here to protect against slowloris type attacks.
https://en.wikipedia.org/wiki/Slowloris_(computer_security)

SetDeadline() could have taken a Duration, but it reads weird. A
deadline usually refers to a specific time, not an amount of time from
now.

That makes a lot more sense. Thanks.

The documentation could perhaps be clearer on this distinction: "A deadline is an absolute time after which I/O operations fail with a timeout (see type Error) instead of blocking." This implies that a deadline and a timeout are the same except that deadlines are absolute.

"The deadline applies to all future I/O, not just the immediately following call to Read or Write. An idle timeout can be implemented by repeatedly extending the deadline after successful Read or Write calls."

One nuance that escaped me here was that a Conn that reaches its deadline is irrevocably in a timeout state; you can't just extend the deadline and try again. 

Nick Irvine

unread,
Feb 4, 2016, 2:12:27 PM2/4/16
to golang-nuts
The advantage of a deadline is that its meaning is not relative to the start time.  That is, if task A starts subtask B, both can use the same deadline.  Had timeouts been used, A would have to subtract the amount of time elapsed between its start and its call to B, and the subroutine of A that starts B may not know what time A started.

My argument is that both are useful, and that perhaps both should be part of the interface. I think SetTimeout* is best for the general case, but SetDeadline is better for more advanced usage like you mention.

*As Jesse pointed out, this SetTimeout would not be what users expect however, as deadlines end IO at the deadline regardless of having had any previously, unlike timeouts. Therefore to get the usual timeout behaviour, you have to reset the timeout after every read/write.

Jack Christensen

unread,
Feb 4, 2016, 3:10:04 PM2/4/16
to Nick Irvine, golang-nuts


Nick Irvine wrote:

One nuance that escaped me here was that a Conn that reaches its deadline is irrevocably in a timeout state; you can't just extend the deadline and try again. 

Are you sure about this? I'm pretty sure I have successfully continued to use a connection after a timeout.

Jack

Nick Irvine

unread,
Feb 4, 2016, 6:19:39 PM2/4/16
to Jack Christensen, golang-nuts
Jack, honestly I'm not sure any more. I swear I ran into that scenario whilst writing a websocket server. I wrote a small TCP server to prove it, but it works as you describe. https://gist.github.com/nfirvine/145394dee59405c5454e 

Nick Irvine

unread,
Feb 9, 2016, 8:38:24 PM2/9/16
to Jack Christensen, golang-nuts
Ah, I found it. It's not Conns in general, but just websocket Conns[1]:

"SetReadDeadline sets the read deadline on the underlying network connection. After a read has timed out, the websocket connection state is corrupt and all future reads will return an error. A zero value for t means reads will not time out."

Reply all
Reply to author
Forward
0 new messages