Я читал о параметре: timeout в https://hexdocs.pm/postgrex/Postgrex.html#transaction/3, но я не уверен, как его включить,
Вот так (см. Последнюю строку):
Postgrex.transaction(
host_pid,
fn(conn) ->
# do query that takes 5 seconds
# with timeout set to be really big
query = Postgrex.prepare!(conn, "", "SELECT pg_sleep(5)", timeout: 50_000)
stream = Postgrex.stream(conn, query)
result_to_iodata = fn(%Postgrex.Result{rows: rows}) ->
format_query_result(rows)
end
Enum.into(stream, File.stream!("eg"), result_to_iodata)
end,
timeout: 30_000 #30 seconds
)
Всякий раз, когда документы по эликсиру определяют функцию, подобную этой:
func_name(arg1, ...argN, opts \\ [] )
opts
- это список ключевых слов, например:
[{:a, 1}, {:b, 2}]
Однако, еслисписок ключевых слов - это последний аргумент в вызове функции, список ключевых слов можно записать так:
func(arg1, arg2, a: 1, b: 2)
и определение функции получит три аргумента
arg1, arg2, [{:a, 1}, {:b, 2}]
В любом случае значение по умолчанию для: timeout равно:
:timeout - Transaction timeout (default: 15000);
, и ошибка говорит:
соединение недоступно и запрос был сброшен из очереди после 2950ms
Поскольку 2950 < 15000
не похоже на: значение таймаута является источником ошибки.
Сообщение об ошибке продолжается:
соединение недоступно .... Вы можете настроить время ожидания запросов в очереди, используя: queue_target и: queue_interval.См. DBConnection.start_link / 2 для получения дополнительной информации
В этом объясняется, как настроить эти тайм-ауты:
В config/<env>.exs
(где <env>
это dev, test или prod):
config :my_app, MyApp.Repo,
adapter: Ecto.Adapters.Postgres,
pool_size: 10,
migration_timestamps: [type: :utc_datetime_usec],
migration_lock: nil,
queue_target: 5000
Это то, что нам пришлось сделать в последнее время из-за увеличения количества ошибок в производстве.
Также ,
Обработка запросов осуществляется через очередь.Когда DBConnection запущен, есть две соответствующие опции для управления очередью:
:queue_target in milliseconds, defaults to 50ms
:queue_interval in milliseconds, defaults to 1000ms
Наша цель - самое большее ждать: queue_target для соединения.Если все соединения, проверенные во время: queue_interval, занимают больше чем: queue_target, тогда мы удваиваем: queue_target.Если проверка соединений занимает больше времени, чем новая цель, мы начинаем отбрасывать сообщения.
Например, по умолчанию наша цель равна 50 мс.Если проверка всех подключений занимает более 50 мс в течение целой секунды, мы удваиваем цель до 100 мс и начинаем отбрасывать сообщения, если время проверки превышает новый лимит.
Это позволяет нам лучше планировать перегрузки, так какмы можем отклонить запросы до того, как они будут отправлены в базу данных, что в противном случае увеличило бы нагрузку на базу данных, усугубив перегрузку.
Но, если вы не коснулись этих значений по умолчанию, то мне интереснопочему вы видите 2950ms
в сообщении об ошибке, а не что-то ближе к 50 мс или 1000 мс.