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.

Manejando llamadas a API externa simultáneas durante peticiones concurrentes.

Tengo dos controladores que tienen

before_action :get_user

y un método privado en ambos controladores

def get_user
  @user = User.find(params[:id])
  @user.create_profile if @user.profile.nil?
end

El método create_profile hace una llamada API al servicio de terceros para crear el perfil. Cuando dos solicitudes concurrentes golpean estos dos controladores desde el mismo usuario, crea llamadas API duplicadas (dos) cuando el perfil está nulo en la base de datos. ¿Cómo puedo asegurarme de no hacer una solicitud única en lugar de dos aquí?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para evitar llamadas duplicadas a la API cuando dos solicitudes concurrentes llegan a los dos controladores desde el mismo usuario, podemos utilizar un mecanismo de bloqueo.

    Podemos agregar una transacción de base de datos alrededor del método get_user que adquiere un bloqueo de nivel de fila en el registro de Usuario. Con este enfoque, la segunda solicitud esperará a que se complete la primera solicitud antes de continuar.

    Aquí está el método get_user actualizado:

    def get_user
      @user = nil
      User.transaction do
        @user = User.lock.find(params[:id])
        @user.create_profile if @user.profile.nil?
      end
    end
    

    Comenzamos estableciendo @user en nulo para evitar errores en caso de que falle la transacción de base de datos. Luego, envolvemos el código en una transacción y adquirimos un bloqueo de nivel de fila en el registro de Usuario usando el método lock.

    Con esta modificación, la segunda solicitud esperará a que se complete la creación del perfil por parte de la primera solicitud antes de continuar, eliminando así las llamadas duplicadas a la API.

Comments are closed.