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í?
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: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étodolock
.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.