es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Tiempo de espera de Ruby / Rails con hilos: cómo esperar un momento y luego volver a unirse más tarde.

Estoy tratando de ejecutar un proceso en un hilo y, si tarda más de x segundos, redireccionar a una página de espera y luego hacer una actualización ajax.

begin
    Timeout::timeout(10) do
        t = Thread.new do
            begin
                output = do_work
                session[:result] = "hecho"
            rescue Exception => e
                session[:result] = "excepción"
            end
        end
        t.join
    end
    if session[:result] == "hecho"
        redirect_to :done
    else
        redirect_back fallback_location: :root, notice: 'No se puede procesar la solicitud, por favor inténtelo de nuevo.'
    end
rescue Exception => e
    if e.message == "execution expired"
        # esto significa que ha expirado el tiempo de espera, así que redirígelos a "waiting"
        redirect_to waiting_path
    else
        redirect_back fallback_location: :root, notice: 'No se puede procesar la solicitud, por favor inténtelo de nuevo.'
    end
end

Luego, en la página “waiting”, verifica el resultado.

def waiting
    # session[:result] nunca se actualiza
end

¿Qué estoy haciendo mal? Esperaría que si se produce una excepción, el hilo sobreviva, como se evidencia en este experimento simple:

begin
    Timeout::timeout(1) do
        t = Thread.new do
            sleep(5)
            puts "¡Hecho!"
        end
        t.join
    end
rescue Exception => e
    if e.message == "execution expired"
        # esto significa que ha expirado el tiempo de espera, así que imprime "expired"
        puts "¡Expirado!"
    end
end

El código anterior funciona bien y después de 5 segundos, el hilo se completa y muestra la salida.

¿Es esto porque no se puede establecer la sesión en un hilo o algo similar?

Gracias por cualquier ayuda,
Kevin

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Hola Kevin,

    Parece que el problema está relacionado con el hecho de que estás intentando acceder a la sesión en un hilo separado. Rails utiliza un modelo de solicitud/respuesta, por lo que la sesión está vinculada al ciclo específico de solicitud/respuesta. Cuando ejecutas un hilo en segundo plano, no tiene acceso a la sesión durante el ciclo principal de solicitud/respuesta.

    Una forma de solucionar esto es utilizar una caché compartida o una base de datos para almacenar el resultado del proceso en segundo plano. En lugar de establecer la variable de sesión en el hilo, podrías actualizar un registro de base de datos o una entrada de caché con el resultado, y luego verificar ese valor actualizado en la acción de espera. Luego, puedes utilizar una llamada AJAX para verificar periódicamente el valor actualizado y actualizar la página cuando esté disponible.

    Otra opción sería utilizar un sistema de cola de mensajes, como Sidekiq o Resque, para manejar tareas en segundo plano. Estos sistemas te permiten agregar una tarea a una cola, que luego es procesada por un proceso de trabajador separado. El proceso de trabajador puede actualizar la base de datos/caché según sea necesario, y luego puedes usar AJAX para verificar el valor actualizado como antes.

    ¡Espero que esto sea de ayuda! Avísame si tienes alguna otra pregunta.

    Saludos,
    [Tu Nombre]

Comments are closed.