DBの負荷が高くレスポンスが遅延する時に、Ectoでクエリ発行した時のタイムアウト時間を延ばしたい時があると思います。デフォルトでは、15秒になっているので、以下のようにして変更すればOKです。
環境準備
$ mix phx.new tran_testpj
・・・省略
Fetch and install dependencies? [Yn] y
・・・省略
$ cd tran_testpj
$ mix phx.gen.html Blog Post posts title:string body:text
tran_testpj\lib\tran_testpj_web\router.ex
に
resources "/posts", PostController
を追加
defmodule TranTestpjWeb.Router do
use TranTestpjWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, {TranTestpjWeb.LayoutView, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", TranTestpjWeb do
pipe_through :browser
get "/", PageController, :index
resources "/posts", PostController #追加
end
・・・省略
タイムアウト時間の延長
ミリ秒なのでデフォルトの倍の30秒に設定します。
tran_testpj\config\dev.exs
を修正
import Config
# Configure your database
config :tran_testpj, TranTestpj.Repo,
username: "postgres",
password: "postgres",
hostname: "localhost",
database: "tran_testpj_dev",
stacktrace: true,
show_sensitive_data_on_connection_error: true,
pool_size: 10, # カンマを追加
timeout: 30000 # 追加
# For development, we disable any cache and enable
# debugging and code reloading.
・・・省略
動作確認
ターミナルを2つ開いて、1つ目で以下を実行してテーブルロックをかける
$ psql -d tran_testpj_dev -U postgres
tran_testpj_dev=# BEGIN;
BEGIN
tran_testpj_dev=*# LOCK TABLE posts IN EXCLUSIVE MODE;
LOCK TABLE
2つめのターミナルで、プロジェクトフォルダに移動して、以下を実行
$ mix phx.server
ブラウザで以下のURLにアクセスして、フォームに適当な値を入力してSAVEボタンを押す。
http://localhost:4000/posts/new
自身で設定したタイムアウト時間が過ぎれば、ブラウザが遷移し、
以下のエラーメッセージが表示される
tcp send: closed (the connection was closed by the pool, possibly due to a timeout or because the pool has been terminated)
テーブルロックを解除する場合は、テーブルロックしたターミナルで、引き続き以下を入力します。
(動作確認が終わった後に解除ください)
tran_testpj_dev=*# COMMIT;
COMMIT
上記psqlのCOMMITコマンドを、クエリのタイムアウト前に実行すると、
エラー無く、DBにフォーム入力したデータが登録されます。
これでは、上記エラーでも明記されている通り、クエリがpoolされ、実行待ちになっているためです。
Ectoだと、特別な考慮をすることなく、発行したクエリが自動的にpoolされ、DBのロックが解除されれば、DB処理を続行してくれるので、とても便利です。
以上