Saltar al contenido

¿Aumentar temporalmente ‘statement_timeout’ para consultas de Postgres en Rails?

Solución:

Creo que puede lograrlo solo cambiando el statement_timeout para toda la conexión, luego revertirlo:

  def execute_expensive_query
    ActiveRecord::Base.connection.execute 'SET statement_timeout = 600000' # 10 minutes
    # DB query with long execution time
  ensure
    ActiveRecord::Base.connection.execute 'SET statement_timeout = 5000' # 5 seconds
  end

En el nivel de base de datos, puede configurar statement_timeout para la transacción actual solo según esta guía:

BEGIN;
SET LOCAL statement_timeout = 250;
...
COMMIT;

Para ampliar la respuesta aceptada, así es como se podría implementar un módulo DatabaseTimeout, eso también se asegura de restablecer el statement_timeout volver a su valor original.

# Ruby's `Timeout` doesn't prevent queries from running for a long time.
#
# To prove this, run the following in a console (yes, twice):
#   Timeout.timeout(1.second) { ActiveRecord::Base.connection.execute('SELECT pg_sleep(100);') }
#   Timeout.timeout(1.second) { ActiveRecord::Base.connection.execute('SELECT pg_sleep(100);') }
# => The 2nd call should run for a long time.
#
# DatabaseTimeout's purpose is to enforce that each query doesn't run for more than the given timeout:
#   DatabaseTimeout.timeout(1.second) { ActiveRecord::Base.connection.execute('SELECT pg_sleep(100);') }
#   DatabaseTimeout.timeout(1.second) { ActiveRecord::Base.connection.execute('SELECT pg_sleep(100);') }
# => Both queries are interrupted after 1 second
module DatabaseTimeout
  # Usage: DatabaseTimeout.timeout(10) { run_some_query }
  def self.timeout(nb_seconds)
    original_timeout = ActiveRecord::Base.connection.execute('SHOW statement_timeout').first['statement_timeout']
    ActiveRecord::Base.connection.execute("SET statement_timeout="#{nb_seconds.to_i}s"")
    yield
  ensure
    if original_timeout
      ActiveRecord::Base.connection.execute("SET statement_timeout = #{original_timeout}")
    end
  end
end
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *