Sharing Channels Between Threads Using Locks #667
-
Hello! In the Bunny documentation I cannot quite tell if you guys are saying channels should only be used by one thread EVER or one thread at a time (i.e. using synchronization). e.g. is it possible for the following script to cause the concurrency issues mentioned in the docs? class ChannelPool
def initialize(channel)
@channel = channel
@mutex = Mutex.new
end
def take
@mutex.synchronize do
yield @channel
end
end
end
pool = ChannelPool.new
Thread.new do
while true do
pool.take do |channel|
channel.exchange('foo', type: :fanout, durable: true, auto_delete: false)
end
end
end
Thread.new do
while true do
pool.take do |channel|
channel.exchange('bar', type: :fanout, durable: true, auto_delete: false)
end
end
end |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 7 replies
-
This code assumes that However, what's the point of declaring exchanges if you are not going to publish anything? And
So even with synchronised writes of individual frames, you have to be really careful about not ending up with a sequence like this
This will cause an unrecoverable connection exception. It is much safer to simply not share channel instances between threads. |
Beta Was this translation helpful? Give feedback.
This code assumes that
Bunny::Channel#exchange
calls cannot result in any kind of interleaving of frames on the wire. Right now this is generally true, andexchange.declare
is a single protocol frame, and Bunny writes frames to the socket with synchronisation.However, what's the point of declaring exchanges if you are not going to publish anything? And
Bunny::Channel#publish
produces two or more frames, depending on message size:So even with synchronised writes of individual frames, you have to be really careful about not ending up with a sequence like this