· 2分で読了

Goでconnection lostをどう処理するか?

この記事は中国語から自動翻訳されたものです。翻訳によりニュアンスが失われている場合があります。

現在人気のある sql パッケージを少し調べてみたところ、connection lostが発生した際に即座にエラーを出してくれるような機能がほとんど存在しないことに気づいた。例えば nodejs の mysql では、connection.on(‘error’) を使ってエラーを監視できる。

しかし golang(少なくともいくつかの人気のあるパッケージ)では、そういった機能がない。もう少し踏み込んで調べてみれば、その理由も理解できなくはない。

The sql package creates and frees connections automatically; it also maintains a free pool of idle connections. If the database has a concept of per-connection state, such state can be reliably observed within a transaction (Tx) or connection (Conn). Once DB.Begin is called, the returned Tx is bound to a single connection. Once Commit or Rollback is called on the transaction, that transaction’s connection is returned to DB’s idle connection pool. The pool size can be controlled with SetMaxIdleConns.

簡単に言うと、sql.Open を呼び出した時点では実際にはconnectionは確立されず、内部でconnection poolが維持され、必要になったときに初めて接続を試みる仕様になっている。つまり、Queryを実行している最中にネットワークの問題でconnection lostが発生した場合、database/sql が水面下で自動的にretryを試みてくれるわけだ。

実のところ、これは良いことでもあって、自分でリトライのロジックを書かずに済む。だが、queryを発行して初めてconnection lostだったと知るのではなく、それ以前にアプリケーション全体でその事態を把握しておきたい場合もある。僕としては、その前にアプリケーション側で検知したいのだ。

もし似たようなことを実現したいなら、低層の Dialer ロジックを書き換えて、network が切断されたときにプログラムへ即座に通知できるようにする必要がある。

関連記事

他のトピックを探索