Redis
 sql >> Base de données >  >> NoSQL >> Redis

Rescue Timeout ::Erreur de Redis Gem (Ruby)

Vous avez exécuté ce code dans irb, n'est-ce pas ? L'exception que vous obtenez n'est pas réellement levée par Redis.new . Il est levé par le inspect méthode, qu'irb appelle pour vous montrer la valeur de l'expression que vous venez de taper.

Il suffit de regarder la trace de la pile (j'ai raccourci les chemins pour la rendre lisible) :

ruby-1.8.7-p330 :009 >   Redis.new(:host => "google.com")
Timeout::Error: time's up!
    from /.../SystemTimer-1.2.3/lib/system_timer/concurrent_timer_pool.rb:63:in `trigger_next_expired_timer_at'
    from /.../SystemTimer-1.2.3/lib/system_timer/concurrent_timer_pool.rb:68:in `trigger_next_expired_timer'
    from /.../SystemTimer-1.2.3/lib/system_timer.rb:85:in `install_ruby_sigalrm_handler'
    from /..../lib/ruby/1.8/monitor.rb:242:in `synchronize'
    from /.../SystemTimer-1.2.3/lib/system_timer.rb:83:in `install_ruby_sigalrm_handler'
    from /.../redis-2.2.2/lib/redis/connection/ruby.rb:26:in `call'
    from /.../redis-2.2.2/lib/redis/connection/ruby.rb:26:in `initialize'
    from /.../redis-2.2.2/lib/redis/connection/ruby.rb:26:in `new'
    from /.../redis-2.2.2/lib/redis/connection/ruby.rb:26:in `connect'
    from /.../SystemTimer-1.2.3/lib/system_timer.rb:60:in `timeout_after'
    from /.../redis-2.2.2/lib/redis/connection/ruby.rb:115:in `with_timeout'
    from /.../redis-2.2.2/lib/redis/connection/ruby.rb:25:in `connect'
    from /.../redis-2.2.2/lib/redis/client.rb:227:in `establish_connection'
    from /.../redis-2.2.2/lib/redis/client.rb:23:in `connect'
    from /.../redis-2.2.2/lib/redis/client.rb:247:in `ensure_connected'
    from /.../redis-2.2.2/lib/redis/client.rb:137:in `process'
... 2 levels...
    from /.../redis-2.2.2/lib/redis/client.rb:46:in `call'
    from /.../redis-2.2.2/lib/redis.rb:90:in `info'
    from /..../lib/ruby/1.8/monitor.rb:242:in `synchronize'
    from /.../redis-2.2.2/lib/redis.rb:89:in `info'
    from /.../redis-2.2.2/lib/redis.rb:1075:in `inspect'
    from /..../lib/ruby/1.8/monitor.rb:242:in `synchronize'
    from /.../redis-2.2.2/lib/redis.rb:1074:in `inspect'
    from /..../lib/ruby/1.8/irb.rb:310:in `output_value'
    from /..../lib/ruby/1.8/irb.rb:159:in `eval_input'
    from /..../lib/ruby/1.8/irb.rb:271:in `signal_status'
    from /..../lib/ruby/1.8/irb.rb:155:in `eval_input'
    from /..../lib/ruby/1.8/irb.rb:154:in `eval_input'
    from /..../lib/ruby/1.8/irb.rb:71:in `start'
    from /..../lib/ruby/1.8/irb.rb:70:in `catch'
    from /..../lib/ruby/1.8/irb.rb:70:in `start'
    from /..../bin/irb:17

Comme vous pouvez le voir ci-dessus, l'exception se produit dans inspect , et non Redis.new . Lorsque vous appelez inspect sur un objet Redis, au lieu de simplement imprimer son état, il fait en fait beaucoup de choses. Dans ce cas, inspect tente de se connecter au serveur et lève une exception lorsque cela expire. Cela me semble être une très mauvaise conception et nous devrions peut-être déposer un rapport de bogue auprès des responsables de la gemme Redis.

Cela conduit à un comportement intéressant dans IRB :

  • Saisir Redis.new(:host => "google.com") génère une exception comme indiqué ci-dessus
  • Tapez Redis.new(:host => "google.com"); 'hello' résultats dans '=> "hello" '

Si vous voulez intercepter cette exception, essayez d'appeler ensure_connected à l'intérieur de votre bloc début/sauvetage/fin.