pattern for timing out on a channel send?

3,972 views
Skip to first unread message

Jerry Worthey

unread,
Nov 2, 2012, 5:32:10 PM11/2/12
to golan...@googlegroups.com
So if I'm receiving stuff from a channel, I can use select to timeout:

select {
case y := <-ch:
        fmt.Println(y)
case <-time.After(200 * time.Millisecond):
        fmt.Println("timed out")
}

What's the best way to time out a channel send?  I'd like to do something like:

select {
case ch <- y:
        fmt.Println("sent y to ch")
case <-time.After(200 * time.Millisecond):
        fmt.Println("timed out")
}                

but I know select is only for receive operations.  

If it times out, I want to make sure the original send never completes.

The reason I want this is I have some code where ch is buffered and occasionally it fills up for a while and the code that sends stuff to ch then starts blocking and causing problems.  Instead of blocking for a long time, I'd like to do something else like save the data to a file until the channel isn't full.  Perhaps just checking the length of the channel is best and going into failsafe mode when len(ch) / cap(ch) > 0.95?  But a timeout on the send would also work...

Thanks!

David Anderson

unread,
Nov 2, 2012, 5:33:33 PM11/2/12
to Jerry Worthey, golan...@googlegroups.com
On Fri, Nov 2, 2012 at 2:32 PM, Jerry Worthey <jwor...@gmail.com> wrote:
So if I'm receiving stuff from a channel, I can use select to timeout:

select {
case y := <-ch:
        fmt.Println(y)
case <-time.After(200 * time.Millisecond):
        fmt.Println("timed out")
}

What's the best way to time out a channel send?  I'd like to do something like:

select {
case ch <- y:
        fmt.Println("sent y to ch")
case <-time.After(200 * time.Millisecond):
        fmt.Println("timed out")
}                

but I know select is only for receive operations.  

Select also works with send operations. One of the channel operations in the select statement will proceed. That statement can be a send or a receive.

- Dave
 

If it times out, I want to make sure the original send never completes.

The reason I want this is I have some code where ch is buffered and occasionally it fills up for a while and the code that sends stuff to ch then starts blocking and causing problems.  Instead of blocking for a long time, I'd like to do something else like save the data to a file until the channel isn't full.  Perhaps just checking the length of the channel is best and going into failsafe mode when len(ch) / cap(ch) > 0.95?  But a timeout on the send would also work...

Thanks!

--
 
 

Jerry Worthey

unread,
Nov 2, 2012, 5:39:15 PM11/2/12
to David Anderson, golan...@googlegroups.com
Oh, thanks.  I'm an idiot...apparently I can't read (or even try code out).

bryanturley

unread,
Nov 2, 2012, 5:58:31 PM11/2/12
to golan...@googlegroups.com
I think this is what you are looking for
select {
  case ch <- x:
    // sent x down ch and didn't block
  default:
    // sent nothing and would have blocked
}

Reply all
Reply to author
Forward
0 new messages