Redis
 sql >> Datenbank >  >> NoSQL >> Redis

Rescue Timeout::Fehler von Redis Gem (Ruby)

Sie haben diesen Code in irb ausgeführt, richtig? Die Ausnahme, die Sie erhalten, wird nicht wirklich von Redis.new ausgelöst . Es wird von inspect ausgelöst -Methode, die irb aufruft, um Ihnen den Wert des gerade eingegebenen Ausdrucks anzuzeigen.

Schauen Sie sich einfach den Stack-Trace an (ich habe die Pfade verkürzt, um ihn lesbar zu machen):

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

Wie Sie oben sehen können, tritt die Ausnahme innerhalb von inspect auf , nicht Redis.new . Wenn Sie inspect aufrufen auf einem Redis-Objekt, anstatt nur seinen Zustand auszudrucken, macht es tatsächlich eine Menge Dinge. In diesem Fall inspect versucht, eine Verbindung zum Server herzustellen, und löst eine Ausnahme aus, wenn das Zeitlimit überschritten wird. Das scheint mir ein sehr schlechtes Design zu sein und vielleicht sollten wir einen Fehlerbericht an die Betreuer des Redis-Juwels senden.

Dies führt zu einem interessanten Verhalten in IRB:

  • Geben Sie Redis.new(:host => "google.com") ein führt zu einer Ausnahme wie oben gezeigt
  • Eingabe von Redis.new(:host => "google.com"); 'hello' ergibt '=> "hello" '

Wenn Sie diese Ausnahme abfangen möchten, versuchen Sie, ensure_connected aufzurufen innerhalb Ihres Begin/Rescue/End-Blocks.