一个简单demo展示应用接口使用goroutine优雅退出

package main

import (
	"context"
	"errors"
	"log"
	"net/http"
	"sync"
	"time"
)

type Tracker struct {
	wg sync.WaitGroup
}

type App struct {
	track Tracker
}

func (a *App) Handle(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusCreated)
	a.track.Event("this event")

}

// 同步处理延时较大,使用异步处理。
func (t *Tracker) Event(data string) {
	t.wg.Add(1)
	go func() {
		defer t.wg.Done()
		time.Sleep(time.Millisecond)
		log.Println(data)
	}()
}

func (t *Tracker) Shutdown(ctx context.Context) error {
	ch := make(chan struct{})
	go func() {
		t.wg.Wait()
		close(ch)
	}()
	select {
	case <- ch:
		return nil
	case <- ctx.Done():
		return errors.New("timeout")
	}
}

func main() {
	var a App
	ctx, cancel := context.WithTimeout(context.Background(), time.Second * 5)
	defer cancel()
	err := a.track.Shutdown(ctx)
	if err != nil {
		log.Println(err)
	}
}

posted on 2022-03-08 15:48  biwentao  阅读(42)  评论(0编辑  收藏  举报

导航