Slide 1

Slide 1 text

ґଘํ޲ͷ͋Δ
 8PSLFSΛ؅ཧ͢Δ 6NFEBHP4QSJOH

Slide 2

Slide 2 text

ґଘํ޲ͷ͋Δ
 8PSLFSΛ؅ཧ͢Δ ࢭΊΔ 6NFEBHP4QSJOH

Slide 3

Slide 3 text

8JLJΈ͍ͨͳαʔϏεͰΑ͋͘Δ΍ͭ w ࣗ෼ͷهࣄͷ಺༰Λશͯμ΢ϯϩʔυ͍ͨ͠ Ὂ %VNQϦΫΤετΛૹΔ Ὂ ཪଆͰॲཧΛ૸ΒͤΔ Ὂ Ϣʔβʔʹରͯ͠μ΢ϯϩʔυՄೳͷ௨஌ΛૹΔ !3

Slide 4

Slide 4 text

"1*4FSWFS %VNQ8PSLFS /PUJpDBUJPO
 8PSLFS 3FRVFTU ϝʔϧͱ͔

Slide 5

Slide 5 text

"1*4FSWFS %VNQ8PSLFS /PUJpDBUJPO
 8PSLFS 3FRVFTU ϝʔϧͱ͔ DIBOOFM DIBOOFM HSPVUJOF HSPVUJOF HSPVUJOF

Slide 6

Slide 6 text

Ͳ͏΍ͬͯࢭΊΔʁ w 04ͷγάφϧΛݟͯॱ൪ʹࢭΊ͍͖͍ͯͨ w طʹड͚෇͚ͨ%VNQॲཧ͸ऴΘΒ͔ͤͯΒࢭΊ͍ͨ Ὂ ΋͘͠͸ద੾ʹୀආͤ͞Δ w DPOUFYUΛ࢖͑͹Ͱ͖ͦ͏ !6

Slide 7

Slide 7 text

"1*4FSWFS %VNQ8PSLFS /PUJpDBUJPO
 8PSLFS 4JHOBM
 8BUDIFS TZTDBMM4*(*/5
 TZTDBMM4*(5&3. DBODFM DMPTF DI DBODFM DMPTF DI DBODFM DMPTF DI PT&YJU

Slide 8

Slide 8 text

4JHOBM8BUDIFS w 4*(*/5ͱ4*(5&3.Λ؂ࢹ Ὂ ड৴ͨ͠Β"1*4FSWFSʹ౉ͨ͠DPOUFYU ͷcancel()Λ࣮ߦ w sigStopCh Ὂ શମͷॲཧ͕ऴ͔ྃͨ͠Ͳ͏͔ΛݟΔ ▷ ࿈ଓͰγάφϧ͕དྷͯ΋େৎ෉ • golang.org/x/sync/errgroup Ὂ HPSPVUJOFͷ؅ཧ͕͠΍͍͢Α͏ʹ !8 eg, ctx := errgroup.WithContext(context.Background()) srvCtx, srvCancel := context.WithCancel(ctx) sigCh := make(chan os.Signal) sigStopCh := make(chan struct{}) signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) eg.Go(func() error { defer close(sigCh) for { select { case <-sigStopCh: log.Println("finish signal watching") return nil case sig := <-sigCh: log.Printf("received signal %+v\n", sig) srvCancel() } } })

Slide 9

Slide 9 text

"1*4FSWFS w BQJEVNQ͕ୟ͔ΕΔͱɼ
 DumpIds DIBOOFM ʹσʔλΛ٧ΊΔ Ὂ CMPDL͕ൃੜ͢ΔͷͰຊ౰͸ྑ͘ͳ͍ w γάφϧʹΑͬͯDUY͕Ωϟϯηϧ͞ΕͨΒɼ Shutdown()ΛݺͿ Ὂ ͍͍ײ͡ʹ(SBDFGVM4IVUEPXOͯ͘͠ΕΔʁ Ὂ ໌ࣔతʹClose()͠ͳ͍ͱ௨৴தͷॲཧ͸
 λΠϜΞ΢τͯ͘͠Εͳ͍ʁ w %VNQͷDUYΛΩϟϯηϧ͠ɼ
 DIBOOFMΛด͡Δ !9 func (s *APIServer) Run(...) ... { ... go func() { log.Println("start server") err := srv.ListenAndServe() if err != nil { log.Print(err) } }() defer close(s.DumpIds) defer cancelDump() <-ctx.Done() ctxShutdown, _ := context.WithTimeout(...) if err := srv.Shutdown(ctxShutdown); err != nil { log.Print(err) } log.Println("shutdown server!!") ... }

Slide 10

Slide 10 text

%VNQ8PSLFS w DIBOOFM dumpIds ʹ٧·͍ͬͯΔ
 σʔλΛҰ୴ୀආ͍ͤͨ͞৔߹͸ɼ
 ctxͷDone()ΛݟͯϋϯυϦϯά͢Δ Ὂ dompIds͸DMPTF͞ΕͯΔͷͰɼೖͬͯΔ σʔλΛॲཧ͖͠Ε͹GPS͸ൈ͚Δ w ࠷ޙʹ/PUJpDBUJPO8PSLFSͷDUYΛ Ωϟϯηϧ͠ɼDIBOOFMΛด͡Δ !10 eg.Go(func() error { defer close(notificationMsgs) defer notificationCancel() defer log.Println("shutdown dump worker") for d := range dumpIds { select { case <-dumpCtx.Done(): // TODO: save dump ids return nil default: time.Sleep(5 * time.Second) log.Printf("dump: %#v\n", d) notificationMsgs <- dumpData(d) } } return nil })

Slide 11

Slide 11 text

/PUJpDBUJPO8PSLFS w %VNQ8PSLFSͱಉ͡ !11 eg.Go(func() error { defer log.Println("shutdown notification worker") defer close(sigStopCh) for msg := range notificationMsgs { select { case <-notificationCtx.Done(): // TODO: save messages return nil default: time.Sleep(4 * time.Second) sendNotification(msg) log.Printf("notification message: %s\n", msg) } } return nil })

Slide 12

Slide 12 text

ࢀߟ࣮૷ w HJTUHJUIVCDPNUBYJPCDFBECGBCDFEFGB w HJUIVCDPNXBOUFEMZTVCFF !12