Stumble upon reading ZeroMQ FAQ about a Thread safety.
My multi-threaded program keeps crashing in weird places inside the ZeroMQ library. What am I d
This answer isn't a good solution to your problem, and definitely go with what user3666197 suggests. I think this solution has potential to work, but also at a large scale there may be performance costs due to mutex congestion.
Question 1: Assuming that async spawn new Thread(every time) and write_socket is shared between the all threads and zeromq says that their socket is not threaded safe. I certainly see write_socket running into threads safety issue. (Btw hasn't faced this issue in all end to end testing thus far.) Is my understanding correct on this?
From my understanding of the documentation, yes, this could be an issue because the sockets are not thread safe. Even if you are not experiencing the issue, it could pop up later.
Question 2: Context Switching can happen(anywhere) inside(even on critical section)
Yes, so one way we could potentially get around this is with a mutex/semaphore to make sure we don't have a context switch happen at the wrong time.
I would do something like this, but there might be a slightly better approach depending on what methods being called are not thread safe:
Celluloid::ZMQ.init
module Scp
module DataStore
class DataSocket
include Celluloid::ZMQ
def initialize
@mutex = Mutex.new
end
def pull_socket(socket)
Thread.new do
@mutex.synchronize do
@read_socket = Socket::Pull.new.tap do |read_socket|
## IPC socket
read_socket.connect(socket)
end
end
end.join
end
def push_socket(socket)
Thread.new do
@mutex.synchronize do
@write_socket = Socket::Push.new.tap do |write_socket|
## IPC socket
write_socket.connect(socket)
end
end
end.join
end
def run
# Missing socket arguments here
pull_socket and push_socket and loopify!
end
def loopify!
Thread.new do
@mutex.synchronize do
loop {
async.evaluate_response(read_socket.read_multipart)
}
end
end.join
end
def evaluate_response(data)
return_response(message_id,routing,Parser.parser(data))
end
def return_response(message_id,routing,object)
data = object.to_response
write_socket.send([message_id,routing,data])
end
end
end
end
DataSocket.new.run