Allow safe multi-threaded access to JedisPubSub
If Thread A calls a subscribe method on Jedis it will block on a socket read call waiting for messages or subscription notifications. Thread B is now free to call additional methods on JedisPubSub to change the current subscriptions that thread A is waiting for. Essentially Thread A will do reads on the socket and Thread B will do writes. An issue occurs in that while Thread A is doing reads, in the getObjectMultiBulkReply() method there is an implicit flush() call. This means both Thread A and Thread B may do a write to the socket. Under this situation if Thread A does a flush while Thread B is writing the internal buffer will be corrupted. The fix is to make thread A never call flush(). This allows Thread A to be solely reads and Thread B to be solely writes. Additionally since Thread B is sending commands, the internal pipeline count is incremented and never decremented. So when Thread A terminates it's read it resets the pipeline count.
This commit is contained in:
@@ -202,11 +202,19 @@ public class Connection {
|
||||
return (List<byte[]>) Protocol.read(inputStream);
|
||||
}
|
||||
|
||||
public void resetPipelinedCount() {
|
||||
pipelinedCommands = 0;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Object> getRawObjectMultiBulkReply() {
|
||||
return (List<Object>) Protocol.read(inputStream);
|
||||
}
|
||||
|
||||
public List<Object> getObjectMultiBulkReply() {
|
||||
flush();
|
||||
pipelinedCommands--;
|
||||
return (List<Object>) Protocol.read(inputStream);
|
||||
return getRawObjectMultiBulkReply();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
Reference in New Issue
Block a user