Skip to content

Instantly share code, notes, and snippets.

@lestrrat
Created July 6, 2016 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lestrrat/345bd76e27bbca8c2b2500f86435fc62 to your computer and use it in GitHub Desktop.
Save lestrrat/345bd76e27bbca8c2b2500f86435fc62 to your computer and use it in GitHub Desktop.
俺が本当は欲しかったもの
package main
import (
"fmt"
"math/rand"
"time"
"golang.org/x/net/context"
)
func main() {
rand.Seed(time.Now().UnixNano())
q := make(chan string, 5)
ctx, cancel := context.WithCancel(context.Background())
go fire(ctx, q)
go receive(ctx, q)
time.AfterFunc(10*time.Second, cancel)
<-ctx.Done()
}
func fire(ctx context.Context, q chan string) {
for i := 0; i < 20; i++ {
n := i
delay := 20*rand.Float64()
time.AfterFunc(time.Duration(delay*float64(time.Second)), func() {
select {
case <-ctx.Done():
return
case q <- fmt.Sprintf("foo%d", n):
}
})
}
}
type rcvcmd struct {
cmd string
t time.Time
}
func receive(ctx context.Context, q chan string) {
// ほぼ同時に2つトリガが発生するのが分かっている
var cmds []rcvcmd
var timer <-chan time.Time
for {
select {
case <-ctx.Done():
return
case cmd := <-q:
// 1秒以内なら一緒に処理しちゃうよ
if len(cmds) == 0 {
timer = time.After(time.Second)
}
rcv := rcvcmd{
cmd: cmd,
t: time.Now(),
}
cmds = append(cmds, rcv)
continue
case <-timer:
// 1秒過ぎたらもう受け付けないよ
}
fmt.Println("---")
for _, cmd := range cmds {
fmt.Println(cmd.cmd, cmd.t.Format(time.RFC3339))
}
cmds = []rcvcmd(nil)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment