LoginSignup
2
1

More than 3 years have passed since last update.

【Go】HTTPサーバがexitする直前に、後始末処理を仕込む!(コネクション開放とか)

Last updated at Posted at 2020-03-11

はい:clap:

今回ご紹介するのは、こちらのnasa9084/sygです。
https://github.com/nasa9084/syg

これを使えば、HTTPサーバがexit(停止)する前に、任意のコードを仕込めてしまいます。
ありがてぇ…ありがてぇ…

経緯

GoでHTTPのRESTAPIサービスを作っていて、その中でRedisのコネクションをプールして使いまわす機能を作りました。
そうするとやっぱ、サービスが終了(HTTPサーバが停止)するときにコネクションをちゃんと開放しなきゃですよ。

「でも、http.ListenAndServeを実行してるところにdefer funcを仕掛けりゃいいだけッスよね? ちょろいちょろい♪」

とナメていたら…

defer funcが実行されない!!

どうやらos.Exit(code int)が発動すると、deferがかき消されてしまうとのこと。なんてこったい:innocent:

そこで見つけたのがこちらになります。

用例

例えばこんな感じで、シグナルを受け取ったときに発動するコールバック関数に、好きな後始末処理を仕込むだけ:thumbsup:

私の場合は、プールしてるRedisのコネクションをClose()してます。

package main

import (
    "context"
    "fmt"
    "github.com/go-redis/redis"
    "net/http"
    "os"
    "github.com/nasa9084/syg"
)

var pooledKVSConnectionsMap = make(map[*redis.Options]*redis.Client)

func main() {
    s := &http.Server{Addr: ":8080"}
    waitCh := make(chan struct{})

    cancel := syg.Listen(func(os.Signal) {
        s.Shutdown(context.Background())
        destruct() // <--- 仕込み!
        close(waitCh)
    }, os.Interrupt)
    defer cancel()

    if err := s.ListenAndServe(); err != http.ErrServerClosed {
        fmt.Print("listening server error:" + err.Error())
    }
    <-waitCh
}

func destruct() {
    for _, kvsCon := range pooledKVSConnectionsMap {
        cerr := kvsCon.Close()
        if cerr != nil {
            fmt.Print(cerr)
        } else {
            fmt.Print(kvsCon, " ... closed.")
        }
    }
}

ご注意

github.com/nasa9084/sygREADME.mdがちょっと古いのか、そちらの例ではdefer cancel()のコードが抜けているので、作者様サイトの例コードやsyg_example_test.goなどを参照されると良いかと思います。

さいごに

・・・
というか、そもそも間違ってました・・・

いえ、この記事そのものではないのですが、go-redis/redisはあらかじめコネクションプールの仕組みを内包しており、使い手側は気にせずNewClient(), Close()をして良いそうです:scream:

実際goroutineを使ってNewClient(), Close()を毎度呼ぶコードと比較したのですが、全く問題ありませんでした。

・・・まあ、勉強になったからよし!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1