socketry/async-redis

Wrong subscriptions order in the example leads to wrong results

woto opened this issue · 5 comments

woto commented

Hi, just trying to learn to use a library and stucked with a demo example :)

https://github.com/socketry/async-redis#subscriptions
When i'm running it, it's freezes like this:

➜  smart git:(B2C-1494) ✗ redis-cli monitor
OK
1561471201.438949 [0 127.0.0.1:49812] "PUBLISH" "status.frontend" "good"
1561471201.439013 [0 127.0.0.1:49810] "SUBSCRIBE" "status.frontend"

Any help appreciate :), thanks.

The problem is due to synchronisation.

To keep the example simple, it's written like this.

But obviously subscribing and publishing to the same channel has a race condition. Even in real systems.

A simple fix is probably just to add a time delay:

require 'async/redis'
require 'json'

endpoint = Async::Redis.local_endpoint
client = Async::Redis::Client.new(endpoint)
subscribed = Async::Condition.new

Async.run do |task|
	subscriber = task.async do
		client.subscribe 'status.frontend' do |context|
			type, name, message = context.listen
			
			pp type, name, message
		end
	end
	
	task.sleep(5)

	publisher = task.async do
		client.publish 'status.frontend', 'good'
	end
ensure
	client.close
end
woto commented

Hi, thank you for reply.
Oh, but i need to be sure that i will not push message to redis until i will not be subscribed.
In redis-rb I was able to do it like this:

redis.subscribe_with_timeout(5, "news") do |on|
  on.message do |channel, message|
    redis.unsubscribe if message == "exit"
  end
  on.subscribe do |channel, subscriptions|
    ActionCable.server.broadcast "channel", 'exit'

  end
end

https://github.com/redis/redis-rb/blob/master/examples/pubsub.rb

Is there a possibility to make it?

Yes, I updated the example.

woto commented

Great, will try it today. Thank you for all your work!

Awesome! If you are using this in a commercial project, please consider sponsoring the project!