Skip to content

Instantly share code, notes, and snippets.

@bllli
Last active September 19, 2021 09:22
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bllli/7bb6ba09a09fd283f88d47f3b6a1d5d7 to your computer and use it in GitHub Desktop.
Save bllli/7bb6ba09a09fd283f88d47f3b6a1d5d7 to your computer and use it in GitHub Desktop.
package main
import (
"context"
"fmt"
"time"
)
func main() {
tr := NewTracker()
// 是否启动goroutine 应该交给调用者
go tr.Run()
_ = tr.Event(context.Background(), "test1")
_ = tr.Event(context.Background(), "test2")
_ = tr.Event(context.Background(), "test3")
time.Sleep(3 * time.Second)
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second))
defer cancel()
tr.Shutdown(ctx)
_ = tr.Event(context.Background(), "test4") // close channel后再发 会painc
}
type Tracker struct {
ch chan string
stop chan struct{}
}
func NewTracker() *Tracker {
return &Tracker{ch: make(chan string, 10)}
}
func (t *Tracker) Event(ctx context.Context, data string) error {
select {
case t.ch <- data:
return nil
case <-ctx.Done():
return ctx.Err()
}
}
func (t *Tracker) Run() {
for data := range t.ch {
time.Sleep(1 * time.Second)
fmt.Println(data)
}
t.stop <- struct{}{}
}
func (t *Tracker) Shutdown(ctx context.Context) {
close(t.ch)
select {
case <-t.stop:
case <-ctx.Done():
}
}
@lihsai0
Copy link

lihsai0 commented Sep 19, 2021

https://gist.github.com/bllli/7bb6ba09a09fd283f88d47f3b6a1d5d7#file-main-go-L28-L30

应该这样吧?

func NewTracker() *Tracker {
	return &Tracker{
		ch: make(chan string, 10),
		stop: make(chan struct{}),
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment