Redis Lock Implementación -- ruby campo con locking campo con redis camp codereview Relacionados El problema

Redis lock implementation


2
vote

problema

Español

Considerando que soy no implementando distribuido Mecanismo de bloqueo, ¿es este código correcto y claro?

  class RedisLock   class NotAcquired < StandardError; end    def initialize(redis)     @redis = redis   end    def lock(key, expiration_ms)     val = SecureRandom.random_number(100000000000000000).to_s      if @redis.set(key, val, nx: true, px: expiration_ms)       yield       unlock(key, val)       true     else       false     end   end    def lock!(*args, &block)     unless lock(*args, &block)       raise NotAcquired.new("Could not acquire lock with #{args}")     end   end    def unlock(key, val)     check_and_delete = <<-LUA       if redis.call('get', KEYS[1]) == KEYS[2] then         redis.call('del', KEYS[1])       end     LUA      @redis.eval(check_and_delete, [key, val])   end end   RedisLock.new(Redis.current).lock!('key', 10000) { do_something }   
Original en ingles

Considering I'm not implementing distributed lock mechanism, is this code correct and clear?

class RedisLock   class NotAcquired < StandardError; end    def initialize(redis)     @redis = redis   end    def lock(key, expiration_ms)     val = SecureRandom.random_number(100000000000000000).to_s      if @redis.set(key, val, nx: true, px: expiration_ms)       yield       unlock(key, val)       true     else       false     end   end    def lock!(*args, &block)     unless lock(*args, &block)       raise NotAcquired.new("Could not acquire lock with #{args}")     end   end    def unlock(key, val)     check_and_delete = <<-LUA       if redis.call('get', KEYS[1]) == KEYS[2] then         redis.call('del', KEYS[1])       end     LUA      @redis.eval(check_and_delete, [key, val])   end end   RedisLock.new(Redis.current).lock!('key', 10000) { do_something } 
        

Lista de respuestas

1
 
vote

Aquí hay una puñalada para aclarar la intención sin cambiar ninguna de la funcionalidad. No intenté correrlo ni nada, así que no me abranes a la sintaxis.

  grossIncomeafterdeduction3  

y para llamarlo:

  grossIncomeafterdeduction4  
 

Here's a stab at clarifying the intent without changing any of the functionality. I didn't try to run it or anything, so don't hold me to syntax.

# handles locking and unlocking redis for a particular operation class RedisLock   # thrown when a lock cannot be acquired   class NotAcquired < StandardError; end    # since the redis key and ms are used in pretty much every method,   # might as well go ahead and pass them in the constructor.   # set defaults here if there are defaults that make sense.   # make a yardoc comment and describe what these all are.   def initialize(redis: Redis.current, nx: true, redis_key:, expiration_ms:)     @redis = redis     @redis_key = redis_key     @expiration_ms = expiration_ms     @nx = nx   end    # call it with_lock instead of lock   # to make it more apparent it accepts a block   def with_lock!     raise(NotAcquired, "Could not acquire lock with #{args}") unless lock     yield     unlock(redis_key, random_lock_number)     true # do you really need to return true here?   end    def with_lock     with_lock!   rescue NotAcquired     false   end    private    # set instance variables in the initializer, but never call them directly.   attr_reader :redis, :redis_key, :expiration_ms, :nx    def lock     redis.set(redis_key, random_lock_number, nx: nx, px: expiration_ms)   end    # number is a little decieving here when you call `.to_s` at the end.   # can you use SecureRandom.uuid instead?   def random_lock_number     @random_lock_number ||= SecureRandom.random_number(100_000_000_000_000_000).to_s   end    # no need for this to be exposed publicly.   # calling eval directly is usually a bad idea.   def unlock     redis.eval(redis_check_and_delete, [redis_key, random_lock_number])   end    def redis_check_and_delete     <<-LUA       if redis.call('get', KEYS[1]) == KEYS[2] then         redis.call('del', KEYS[1])       end     LUA   end end 

And to call it:

RedisLock.new(redis_key: 'key', expiration_ms: 10000).with_lock! { do_something } 
 
 
   
   

Relacionados problema

3  Autenticación de registro de usuario  ( User logging authentication ) 
Estoy poco frustrado porque no sé qué tan bien puedo refactorizar este script. Escribí la función de autenticación, pero es demasiado complicada, tal vez dema...

3  Modelo para aplicaciones web  ( Model for web applications ) 
Estoy desarrollando un modelo para aplicaciones web. La base de datos que yo uso es Redis. He creado un DbField como HashDbField , SortedSetDbField2 , ...

4  Obtener el manejador de eventos  ( Get event handler ) 
Estoy trabajando en mi primera aplicación Nodejs / Express con el módulo ASYNC. Ha sido una batalla cuesta arriba para mí aprender nodo (e incluso Javascript)...

3  Spring Oauth2 Token Store admitido por Redis  ( Spring oauth2 token store supported by redis ) 
Tuve que hacer una demostración para la primavera outh2 con la tienda Redis para tokens. Comenzó con la aplicación SPOKLR2 (con tonr2) de muestra de aquí . S...

5  Tienda CSV en Redis  ( Store csv in redis ) 
Necesitaba hacer un script pequeño para leer un archivo CSV y almacenar 2 columnas en Redis. ¿Pueden los chicos echar un vistazo al código y avisarme cómo pue...

2  El raspador web extrae los archivos ZIP y los publica a Redis  ( Web scraper extracts zip files and publishes them to redis ) 
Escribí este programa para una entrevista de trabajo un poco. Me gustaría comentarios generales sobre estilo, legibilidad, mantenimiento o cualquier falla obv...

5  Docker-compone para API de matraz basado en tareas con Redis y RQ  ( Docker compose for task based flask api with redis and rq ) 
No soy un Gurú de Docker o Expert in Flask o Redis. Sin embargo, necesito aprovechar estas tecnologías. Me las arreglé para guijarme algo juntos que funciona ...

1  Escriba millones de líneas a un archivo - Python, DataFrames y Redis [CERRADO]  ( Write millions of lines to a file python dataframes and redis ) 
cerrado. Esta pregunta es off-topic . Actualmente no está aceptando respuestas. ¿Quieres ...

1  Datos de primavera Redis - ¿Relaciones de objetos de mapeo?  ( Spring data redis mapping object relationships ) 
Estoy diseñando una aplicación que procesará un conjunto de mensajes de redes sociales que son publicados por los usuarios. Cada mensaje se califica y hay una...

19  API para mirar el código postal japonés  ( Api for looking up japanese postal code ) 
La mayor parte de mi experiencia es en Python, Java e incrustada C, y necesito aprender Scala y jugar para un nuevo trabajo. Como ejercicio, decidí crear una ...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos