Sequel + MySQL2でSQLの実行を終えてもコネクションがクローズされない

# はじめに
ruby用DBアクセスライブラリ [Sequel](http://sequel.jeremyevans.net/) を使用した場合、てっきりライブラリ側で使用後のコネクションをクローズしてくれるものだと思ってました。

でも正しい実装を行わないとクローズされないことが判明。

# 検証
まず以下のようなテーブルを用意

```
mysql> select * from table01;
+------+--------+--------+
| id   | name   | status |
+------+--------+--------+
|    1 | 田中   |      0 |
|    2 | 佐藤   |      1 |
+------+--------+--------+
2 rows in set (0.00 sec)
```

table01 のレコードを検索する `@adapter.fetch` ブロック内で10秒、ブロックを抜けたところで10秒 sleep してみる。

```rb:sequel_mysql.rb
require 'sequel'

class SequelMysql

  def initialize
    @adapter = Sequel.mysql2(
      :host=>'localhost',
      :user=>'root',
      :password=>'**',
      :database=>'sample',
    )

    run
  end

  def run
    sql = 'SELECT * FROM table01'
    @adapter.fetch(sql) {|r|
      # ここのブロックを抜けるとコネクションがクローズされる想定なので、20秒（10秒＊2レコード）たったらMySQL実行プロセスから消えるはず
      sleep 10
    }
    sleep 10
  end

end

SequelMysql.new
```

しかし20秒たってもプロセスは消えず。
30秒（ブロック内20秒 + ブロック外10秒）たってようやく消えた。

```
mysql> show processlist;
+----+------+-----------+--------+---------+------+-------+------------------+
| Id | User | Host      | db     | Command | Time | State | Info             |
+----+------+-----------+--------+---------+------+-------+------------------+
| 40 | root | localhost | sample | Query   |    0 | NULL  | show processlist |
| 61 | root | localhost | sample | Sleep   |   29 |       | NULL             |
+----+------+-----------+--------+---------+------+-------+------------------+
2 rows in set (0.00 sec)

mysql> show processlist;
+----+------+-----------+--------+---------+------+-------+------------------+
| Id | User | Host      | db     | Command | Time | State | Info             |
+----+------+-----------+--------+---------+------+-------+------------------+
| 40 | root | localhost | sample | Query   |    0 | NULL  | show processlist |
| 61 | root | localhost | sample | Sleep   |   30 |       | NULL             |
+----+------+-----------+--------+---------+------+-------+------------------+
2 rows in set (0.00 sec)

mysql> show processlist;
+----+------+-----------+--------+---------+------+-------+------------------+
| Id | User | Host      | db     | Command | Time | State | Info             |
+----+------+-----------+--------+---------+------+-------+------------------+
| 40 | root | localhost | sample | Query   |    0 | NULL  | show processlist |
+----+------+-----------+--------+---------+------+-------+------------------+
1 row in set (0.00 sec)
```

# 正しい実装は

コネクション接続処理

```
    @adapter = Sequel.mysql2(
      :host=>'localhost',
      :user=>'root',
      :password=>'**',
      :database=>'sample',
    )
```

にブロックを渡し、そこでの処理を抜けるときにクローズしてくれるらしい。[^1]

```
    @adapter = Sequel.mysql2(
      :host=>'localhost',
      :user=>'root',
      :password=>'**',
      :database=>'sample',
    )) {|db|
      # ここを抜けるとクローズ
    }
```

# 再検証

`@adapter.fetch` を廃止。
代わりにコネクション接続処理のブロック内で table01 のレコードを検索する `db[:table01].all` を使用。
そしてブロック内で10秒、ブロックを抜けたところで10秒 sleep してみる。

```rb:sequel_mysql.rb
require 'sequel'

class SequelMysql

  def initialize
    @adapter = Sequel.mysql2(
      :host=>'localhost',
      :user=>'root',
      :password=>'1qazxsw2',
      :database=>'sample',
    ) {|db|
      p db[:table01].all
      # ここのブロックを抜けるとコネクションがクローズされる想定なので、10秒たったらMySQL実行プロセスから消えるはず
      sleep 10
    }
    sleep 10
  end

end

SequelMysql.new
```

結果は、、、10秒たったら正しくプロセスから消えました。

```
mysql> show processlist;
+----+------+-----------+--------+---------+------+-------+------------------+
| Id | User | Host      | db     | Command | Time | State | Info             |
+----+------+-----------+--------+---------+------+-------+------------------+
| 40 | root | localhost | sample | Query   |    0 | NULL  | show processlist |
| 62 | root | localhost | sample | Sleep   |   10 |       | NULL             |
+----+------+-----------+--------+---------+------+-------+------------------+
2 rows in set (0.00 sec)

mysql> show processlist;
+----+------+-----------+--------+---------+------+-------+------------------+
| Id | User | Host      | db     | Command | Time | State | Info             |
+----+------+-----------+--------+---------+------+-------+------------------+
| 40 | root | localhost | sample | Query   |    0 | NULL  | show processlist |
+----+------+-----------+--------+---------+------+-------+------------------+
1 row in set (0.01 sec)
```


[^1]:
http://sequel.jeremyevans.net/rdoc/classes/Sequel.html
> If a block is given to these methods, it is passed the opened Database object, which is closed (disconnected) when the block exits, just like a block passed to connect