LoginSignup
0
0

More than 3 years have passed since last update.

11rep - contextパッケージでテンプレ

Last updated at Posted at 2020-05-17

contextパッケージとは何か

  • Context は、APIのサーバーやクライアントを使うときに、コンテキストを提供してキャンセルや、タイムアウト、値を渡したり出来る仕組み

流れ

  • (*sql.DB)Begin()でトランザクションを開始
  • (*sql.Tx)Commit()でコミット、(*sql.Tx)RollBack()でロールバック
package main

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
    "context"
    "time"
)

func main() {
    db, _ := sql.Open("mysql", "user:password@tcp(host:port)/dbname")

    ctx := context.Background()
    ctx, cancel := context.WithTimeout(ctx, 1*time.Second)
        defer cancel()

    tx, error := db.Begin()
    if error != nil {
        log.Fatal(error)
        return
    }
        defer tx.Close()

    _, err := db.ExecContext(ctx, {Query})
    if err != nil {
      tx.Rollback()
    } else {
      tx.Commit()
    }
}

  • defer cancel() 上記はタイムアウトの実装
  • 1秒以上かかる場合はDone
  • TimeOutの設定は下記

Microsecond = 1000 * Nanosecond

Millisecond = 1000 * Microsecond

Second = 1000 * Millisecond

Minute = 60 * Second

Hour = 60 * Minute

具体的な利用例からcontextとは何かを説明

  • Goの典型的な利用例であるWebアプリケーションを考える
  • Goのサーバにおいてリクエストはそれぞれ個別のgoroutineで処理される
  • そしてリクエストHandlerは新たなgoroutineを生成しバックエンドのDBや別のサーバにリクエストを投げ結果を得てユーザに対してレスポンスを返す.

最初に注意するべきはその処理に適切なTimeoutやDeadlineを設定して処理が停滞するのを防ぐことである

  • 例えば別のサーバにリクエストを投げる場合にネットワークの問題でリクエストに時間がかかってしまうことは大いに考えられる.リクエストにTimeoutを設定して早めにレスポンスを返しリトライを促すべきである.

次に注意するべきは生成したgoroutineを適切にキャンセルしリソースを解放することである.(※Must)

  • 例えば別のサーバにリクエストを投げる場合に適切なキャンセル処理を行わないとTimeout後もネットワークリソースが使われ続けることになる(CPUやメモリを使い続けるかもしれない)
  • この場合net/httpパッケージレベルでリクエストをキャンセルするべきである.
  • さらにそのgoroutineは別のgoroutineを呼び出しそれがまた別の…と呼び出しの連鎖は深くなることが考えられる
    • その場合も親のTimeoutに合わせてその子は全て適切にキャンセルされリソースは解放されるべきである > contextパッケージはこのキャンセルのためのシグナルをAPIの境界を超えて受け渡すための仕組みである.ある関数から別の関数へと,親から子へと,キャンセルを伝搬させる.

参考サイト

0
0
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
0
0