packagemainimport("context""log""os""os/signal""sync""syscall""time")funcwithContextFunc(ctxcontext.Context,ffunc())context.Context{ctx,cancel:=context.WithCancel(ctx)gofunc(){c:=make(chanos.Signal)// register for interupt (Ctrl+C) and SIGTERM (docker)signal.Notify(c,syscall.SIGINT,syscall.SIGTERM,syscall.SIGKILL)defersignal.Stop(c)select{case<-ctx.Done():case<-c:f()cancel()}}()returnctx}funcmain(){jobChan:=make(chanint,100)stopped:=make(chanstruct{})finished:=make(chanstruct{})wg:=&sync.WaitGroup{}ctx:=withContextFunc(context.Background(),func(){log.Println("stop the server")close(stopped)wg.Wait()close(finished)},)// create 4 workers to process jobfori:=0;i<4;i++{gofunc(iint){log.Printf("start worker: %02d",i)for{select{case<-finished:log.Printf("stop worker: %02d",i)returndefault:select{casejob:=<-jobChan:time.Sleep(time.Duration(job*100)*time.Millisecond)log.Printf("worker: %02d, process job: %02d",i,job)wg.Done()default:log.Printf("worker: %02d, no job",i)time.Sleep(1*time.Second)}}}}(i+1)}// send jobgofunc(){fori:=0;i<50;i++{wg.Add(1)select{casejobChan<-i:time.Sleep(100*time.Millisecond)log.Printf("send the job: %02d\n",i)case<-stopped:wg.Done()log.Println("stoped send the job")return}}return}()select{case<-ctx.Done():time.Sleep(1*time.Second)log.Println("server down")}}
$ docker-compose stop -h
Stop running containers without removing them.
They can be started again with `docker-compose start`.
Usage: stop [options] [--] [SERVICE...]
Options:
-t, --timeout TIMEOUT Specify a shutdown timeout in seconds.
(default: 10)