socketry / async-redis

MIT License
83 stars 18 forks source link

DEBUG SLEEP 1 blocks? #2

Closed matti closed 5 years ago

matti commented 5 years ago
require 'sinatra/base'
require 'async/redis'
class MyApp < Sinatra::Base
  get "/" do
    endpoint = Async::Redis.local_endpoint
    client = Async::Redis::Client.new(endpoint)

    client.call "DEBUG", "SLEEP", 1
    puts Time.now
    "ok"
  end
end

use MyApp # Then, it will get to Sinatra.
run lambda {|env| [404, {}, []]} # Bottom of the stack, give 404.

run with

 falcon serve [--threaded|--forked] -n 16 -b http://0.0.0.0:9292

It looks like

client.call "DEBUG", "SLEEP", 1

blocks the Reactor?

output when calling that with ab -n 10 -c 10:

2018-12-26 23:28:02 +0200
2018-12-26 23:28:03 +0200
2018-12-26 23:28:05 +0200
2018-12-26 23:28:05 +0200
2018-12-26 23:28:11 +0200
2018-12-26 23:28:11 +0200
2018-12-26 23:28:11 +0200
2018-12-26 23:28:11 +0200
2018-12-26 23:28:11 +0200
2018-12-26 23:28:11 +0200

what am I not getting?

matti commented 5 years ago

Please note it blocks the whole Redis event loop (all the connections) contrary to BLPOP that would only block one connection.

oh, okay.

ioquatix commented 5 years ago

Haha - that's funny. So, DEBUG SLEEP blocks the entire process? That's a pretty invasive call. Is there some other sleep operation?

ioquatix commented 5 years ago

I adapted your code into a working example:

https://github.com/socketry/falcon/blob/master/examples/redis/config.ru

You need the latest version of async-redis as it returns a negative length array when it times out which wasn't anticipated by the RESP parser.

matti commented 5 years ago

oh that BLPOP sleep is great! Tried to google "simulate slow redis server" hard, but I did't find that.

matti commented 5 years ago

and yes, DEBUG SLEEP blocks whole redis server - it is handy for simulating total black out

ioquatix commented 5 years ago

Let me know how you get on with async-redis I would love to hear about anything you build with it.

matti commented 5 years ago

@ioquatix I'm gonna combine async-redis with Falcon and sidekiq-sync gem I did: offload computation from Falcon to the background so that I don't have to async-* everything I use. sidekiq-sync allows me to call a worker like this: result = ContainsNonAsyncifiedStuffWorker.perform_sync and async-redis keeps the IO non-blocking, using the exactly same BLPOP that you have in your example.

ioquatix commented 5 years ago

Cool, let me know when it's working!