[
https://issues.apache.org/jira/browse/ZOOKEEPER-900?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Reed Wanderman-Milne updated ZOOKEEPER-900:
-------------------------------------------
Attachment: ZOOKEEPER-900-part2.patch
I've attached a patch that fixes the blocking issue in connectOne(). I've moved
much of the conncetion logic into SendWorker, so all the socket operations are
done on a seperate thread. Some of the code in the two connectOne() methods
were moved to SendWorker.conncetToServer. Additionally, receiveConnection() and
initiateConnection() were moved to conncetOne. As a result, conncetOne()
shouldn't wait for the connection to be established before returning.
One consequence of this is that SendWorker.finish() may block for the
connection to be made, if it's called before a connection is established (since
both finish() and SendWorker.establishConnection() are synchronized). This is
better than blocking on connectOne(), but does anyone have any ideas to fix
this?
> FLE implementation should be improved to use non-blocking sockets
> -----------------------------------------------------------------
>
> Key: ZOOKEEPER-900
> URL: https://issues.apache.org/jira/browse/ZOOKEEPER-900
> Project: ZooKeeper
> Issue Type: Bug
> Reporter: Vishal Kher
> Assignee: Vishal Kher
> Priority: Critical
> Fix For: 3.5.1
>
> Attachments: ZOOKEEPER-900-part2.patch, ZOOKEEPER-900.patch,
> ZOOKEEPER-900.patch1, ZOOKEEPER-900.patch2
>
>
> From earlier email exchanges:
> 1. Blocking connects and accepts:
> a) The first problem is in manager.toSend(). This invokes connectOne(), which
> does a blocking connect. While testing, I changed the code so that
> connectOne() starts a new thread called AsyncConnct(). AsyncConnect.run()
> does a socketChannel.connect(). After starting AsyncConnect, connectOne
> starts a timer. connectOne continues with normal operations if the connection
> is established before the timer expires, otherwise, when the timer expires it
> interrupts AsyncConnect() thread and returns. In this way, I can have an
> upper bound on the amount of time we need to wait for connect to succeed. Of
> course, this was a quick fix for my testing. Ideally, we should use Selector
> to do non-blocking connects/accepts. I am planning to do that later once we
> at least have a quick fix for the problem and consensus from others for the
> real fix (this problem is big blocker for us). Note that it is OK to do
> blocking IO in SenderWorker and RecvWorker threads since they block IO to the
> respective peer.
> b) The blocking IO problem is not just restricted to connectOne(), but also
> in receiveConnection(). The Listener thread calls receiveConnection() for
> each incoming connection request. receiveConnection does blocking IO to get
> peer's info (s.read(msgBuffer)). Worse, it invokes connectOne() back to the
> peer that had sent the connection request. All of this is happening from the
> Listener. In short, if a peer fails after initiating a connection, the
> Listener thread won't be able to accept connections from other peers, because
> it would be stuck in read() or connetOne(). Also the code has an inherent
> cycle. initiateConnection() and receiveConnection() will have to be very
> carefully synchronized otherwise, we could run into deadlocks. This code is
> going to be difficult to maintain/modify.
> Also see: https://issues.apache.org/jira/browse/ZOOKEEPER-822
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)