Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value #1257

Closed
wants to merge 2 commits into from

Conversation

swallez
Copy link
Member

@swallez swallez commented Feb 21, 2020

When packets are added to ClientCnxn's outgoing packet queue we ensure there's no conflict with an ongoing flush of that queue because of connection loss.

Synchronization used to be on the state field's value. This value is both not stable (its value changes over time), possibly causing improper synchronization, and global, which can cause contention in applications that run several ZooKeeper clients.

We now synchronize on outgoingQueue which is both local to a ClientCnxn's instance and stable.

@maoling
Copy link
Member

maoling commented Feb 25, 2020

@swallez

  • [ERROR] Synchronization performed on java.util.concurrent.LinkedBlockingDeque in org.apache.zookeeper.ClientCnxn.queuePacket(RequestHeader, ReplyHeader, Record, Record, AsyncCallback, String, String, Object, ZooKeeper$WatchRegistration, WatchDeregistration) [org.apache.zookeeper.ClientCnxn] At ClientCnxn.java:[line 1645]

  • JLM_JSR166_UTILCONCURRENT_MONITORENTER: This method performs synchronization an object that is an instance of a class from the java.util.concurrent package  (or its subclasses). Instances of these classes have their own concurrency  control mechanisms that are orthogonal to the synchronization provided by the  Java keyword synchronized. For example, synchronizing on an AtomicBoolean  will not prevent other threads from modifying the AtomicBoolean. Such code may be correct, but should be  carefully reviewed and documented, and may confuse people who have to  maintain the code at a later date.

@swallez
Copy link
Member Author

swallez commented Feb 27, 2020

@maoling I added a commit to instruct SpotBugs that we know what we're doing, following the approach used to allow synchronized (waitingEvents) in that same class.

@maoling
Copy link
Member

maoling commented Mar 2, 2020

looks good. I still have another thought(no binding for the following, you can ignore it):

  • Since the root cause is a narrow windows between queuePacket and cleanup, so synchronized objectLock is also an alternative way? which one is better? Since outgoingQueue is a critical Queue for client to talk with server, synchronized outgoingQueue will have performance and future program extensibility issue?

Haha, I also test for the global and inner wording by the following way:

  • new two different zookeeper clients, create some znodes, printing the hashcode of outgoingQueue and state. They really hold different outgoingQueue, but the same hashcode of state. it really confuses me.

  • I believe different clients will have different state instance, otherwise when one client calls close()(set state to CLOSE), it will affect another client. However, using following ways cannot reason about it.

System.out.println(zk1.getState() == zk2.getState()); //true
System.out.println(zk1.getState().equals(zk2.getState())); //true
System.out.println(zk1.getState().hashCode() == zk2.getState().hashCode()); //true
System.out.println(System.identityHashCode(zk1.getState()) == System.identityHashCode(zk2.getState().hashCode()); //true

javap to see the bytecode, the value set to state is public static final, so it's really global-shared by multi-clients.

public final class org.apache.zookeeper.States extends java.lang.Enum<org.apache.zookeeper.States> {
  public static final org.apache.zookeeper.States CONNECTING;
  public static final org.apache.zookeeper.States NOT_CONNECTED;
  ********************************************
  private static final org.apache.zookeeper.States[] $VALUES;
  public static org.apache.zookeeper.States[] values();
  • synchronized Enum is also not thread-safe. Look at my demo attached in JIRA.
  • In a word, Enum is a heresy:)

@swallez
Copy link
Member Author

swallez commented Mar 5, 2020

Thanks for the review @maoling!

Synchronizing on outgoingQueue or a separate objectLock has the exact same performance since no other synchronization statement exists for outgoingQueue, including in its implementation (I checked the code for LinkedBlockingDeque).

In terms of future extensibility I don't think this is a concern as outgoingQueue is used in very few places, which are where synchronization is needed.

And yes, enum is great to represent enumerated values but not so great for thread synchronization 😉

Copy link
Contributor

@arshadmohammad arshadmohammad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM +1

Copy link
Contributor

@arshadmohammad arshadmohammad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM +1

@eolivelli
Copy link
Contributor

Can you please revase this patch into latest master?

…le internal value

When packets are added to ClientCnxn's outgoing packet queue we ensure there's no conflict with an ongoing flush of that queue because of connection loss.

Synchronization used to be on the state field's value. This value is both not stable (its value changes over time), possibly causing improper synchronization, and global, which can cause contention in applications that run several ZooKeeper clients.

We now synchronize on outgoingQueue which is both local to a ClientCnxn's instance and stable.
@swallez
Copy link
Member Author

swallez commented Mar 29, 2022

@eolivelli rebase done.

The pr-merge job failed on zookeeper-client-c because of a missing C header file, unrelated to this change.

@asfgit asfgit closed this in 91e0520 Mar 30, 2022
asfgit pushed a commit that referenced this pull request Mar 30, 2022
…le internal value

When packets are added to ClientCnxn's outgoing packet queue we ensure there's no conflict with an ongoing flush of that queue because of connection loss.

Synchronization used to be on the state field's value. This value is both not stable (its value changes over time), possibly causing improper synchronization, and global, which can cause contention in applications that run several ZooKeeper clients.

We now synchronize on outgoingQueue which is both local to a ClientCnxn's instance and stable.

Author: Sylvain Wallez <sylvain@bluxte.net>

Reviewers: maoling <maoling@apache.org>, Mohammad Arshad <arshad@apache.org>

Closes #1257 from swallez/ZOOKEEPER-3652 and squashes the following commits:

82e2cad [Sylvain Wallez] Instruct SpotBugs that we know what we're doing when synchronizing on outgoingQueue
b0bc03d [Sylvain Wallez] ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value

(cherry picked from commit 91e0520)
Signed-off-by: Mohammad Arshad <arshad@apache.org>
asfgit pushed a commit that referenced this pull request Mar 30, 2022
…le internal value

When packets are added to ClientCnxn's outgoing packet queue we ensure there's no conflict with an ongoing flush of that queue because of connection loss.

Synchronization used to be on the state field's value. This value is both not stable (its value changes over time), possibly causing improper synchronization, and global, which can cause contention in applications that run several ZooKeeper clients.

We now synchronize on outgoingQueue which is both local to a ClientCnxn's instance and stable.

Author: Sylvain Wallez <sylvain@bluxte.net>

Reviewers: maoling <maoling@apache.org>, Mohammad Arshad <arshad@apache.org>

Closes #1257 from swallez/ZOOKEEPER-3652 and squashes the following commits:

82e2cad [Sylvain Wallez] Instruct SpotBugs that we know what we're doing when synchronizing on outgoingQueue
b0bc03d [Sylvain Wallez] ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value

(cherry picked from commit 91e0520)
Signed-off-by: Mohammad Arshad <arshad@apache.org>
asfgit pushed a commit that referenced this pull request Mar 30, 2022
…le internal value

When packets are added to ClientCnxn's outgoing packet queue we ensure there's no conflict with an ongoing flush of that queue because of connection loss.

Synchronization used to be on the state field's value. This value is both not stable (its value changes over time), possibly causing improper synchronization, and global, which can cause contention in applications that run several ZooKeeper clients.

We now synchronize on outgoingQueue which is both local to a ClientCnxn's instance and stable.

Author: Sylvain Wallez <sylvain@bluxte.net>

Reviewers: maoling <maoling@apache.org>, Mohammad Arshad <arshad@apache.org>

Closes #1257 from swallez/ZOOKEEPER-3652 and squashes the following commits:

82e2cad [Sylvain Wallez] Instruct SpotBugs that we know what we're doing when synchronizing on outgoingQueue
b0bc03d [Sylvain Wallez] ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value

(cherry picked from commit 91e0520)
Signed-off-by: Mohammad Arshad <arshad@apache.org>
symat pushed a commit to symat/zookeeper that referenced this pull request Apr 5, 2022
…le internal value

When packets are added to ClientCnxn's outgoing packet queue we ensure there's no conflict with an ongoing flush of that queue because of connection loss.

Synchronization used to be on the state field's value. This value is both not stable (its value changes over time), possibly causing improper synchronization, and global, which can cause contention in applications that run several ZooKeeper clients.

We now synchronize on outgoingQueue which is both local to a ClientCnxn's instance and stable.

Author: Sylvain Wallez <sylvain@bluxte.net>

Reviewers: maoling <maoling@apache.org>, Mohammad Arshad <arshad@apache.org>

Closes apache#1257 from swallez/ZOOKEEPER-3652 and squashes the following commits:

82e2cad [Sylvain Wallez] Instruct SpotBugs that we know what we're doing when synchronizing on outgoingQueue
b0bc03d [Sylvain Wallez] ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value

(cherry picked from commit 91e0520)
asfgit pushed a commit that referenced this pull request Apr 6, 2022
…le internal value

When packets are added to ClientCnxn's outgoing packet queue we ensure there's no conflict with an ongoing flush of that queue because of connection loss.

Synchronization used to be on the state field's value. This value is both not stable (its value changes over time), possibly causing improper synchronization, and global, which can cause contention in applications that run several ZooKeeper clients.

We now synchronize on outgoingQueue which is both local to a ClientCnxn's instance and stable.

Author: Sylvain Wallez <sylvainbluxte.net>

Reviewers: maoling <maolingapache.org>, Mohammad Arshad <arshadapache.org>

Closes #1257 from swallez/ZOOKEEPER-3652 and squashes the following commits:

82e2cad [Sylvain Wallez] Instruct SpotBugs that we know what we're doing when synchronizing on outgoingQueue
b0bc03d [Sylvain Wallez] ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value

(cherry picked from commit 91e0520)

Author: Sylvain Wallez <sylvain@bluxte.net>
Author: Mate Szalay-Beko <symat@apache.org>

Reviewers: Sylvain Wallez <sylvain@bluxte.net>, Mohammad Arshad <arshad@apache.org>, maoling <maoling@apache.org>

Closes #1850 from symat/ZOOKEEPER-3652-branch-3.5 and squashes the following commits:

5cd29db [Mate Szalay-Beko] remove formatting changes
e925265 [Sylvain Wallez] ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value
anuragmadnawat1 pushed a commit to anuragmadnawat1/zookeeper that referenced this pull request Oct 31, 2022
…le internal value

When packets are added to ClientCnxn's outgoing packet queue we ensure there's no conflict with an ongoing flush of that queue because of connection loss.

Synchronization used to be on the state field's value. This value is both not stable (its value changes over time), possibly causing improper synchronization, and global, which can cause contention in applications that run several ZooKeeper clients.

We now synchronize on outgoingQueue which is both local to a ClientCnxn's instance and stable.

Author: Sylvain Wallez <sylvain@bluxte.net>

Reviewers: maoling <maoling@apache.org>, Mohammad Arshad <arshad@apache.org>

Closes apache#1257 from swallez/ZOOKEEPER-3652 and squashes the following commits:

82e2cad [Sylvain Wallez] Instruct SpotBugs that we know what we're doing when synchronizing on outgoingQueue
b0bc03d [Sylvain Wallez] ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value
anuragmadnawat1 added a commit to anuragmadnawat1/zookeeper that referenced this pull request Nov 1, 2022
…le internal value (#23)

When packets are added to ClientCnxn's outgoing packet queue we ensure there's no conflict with an ongoing flush of that queue because of connection loss.

Synchronization used to be on the state field's value. This value is both not stable (its value changes over time), possibly causing improper synchronization, and global, which can cause contention in applications that run several ZooKeeper clients.

We now synchronize on outgoingQueue which is both local to a ClientCnxn's instance and stable.

Author: Sylvain Wallez <sylvain@bluxte.net>

Reviewers: maoling <maoling@apache.org>, Mohammad Arshad <arshad@apache.org>

Closes apache#1257 from swallez/ZOOKEEPER-3652 and squashes the following commits:

82e2cad [Sylvain Wallez] Instruct SpotBugs that we know what we're doing when synchronizing on outgoingQueue
b0bc03d [Sylvain Wallez] ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value

Co-authored-by: Sylvain Wallez <sylvain@bluxte.net>
anuragmadnawat1 pushed a commit to anuragmadnawat1/zookeeper that referenced this pull request Nov 1, 2022
…le internal value

When packets are added to ClientCnxn's outgoing packet queue we ensure there's no conflict with an ongoing flush of that queue because of connection loss.

Synchronization used to be on the state field's value. This value is both not stable (its value changes over time), possibly causing improper synchronization, and global, which can cause contention in applications that run several ZooKeeper clients.

We now synchronize on outgoingQueue which is both local to a ClientCnxn's instance and stable.

Author: Sylvain Wallez <sylvain@bluxte.net>

Reviewers: maoling <maoling@apache.org>, Mohammad Arshad <arshad@apache.org>

Closes apache#1257 from swallez/ZOOKEEPER-3652 and squashes the following commits:

82e2cad [Sylvain Wallez] Instruct SpotBugs that we know what we're doing when synchronizing on outgoingQueue
b0bc03d [Sylvain Wallez] ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value
anuragmadnawat1 added a commit to anuragmadnawat1/zookeeper that referenced this pull request Nov 1, 2022
…le internal value (#49)

When packets are added to ClientCnxn's outgoing packet queue we ensure there's no conflict with an ongoing flush of that queue because of connection loss.

Synchronization used to be on the state field's value. This value is both not stable (its value changes over time), possibly causing improper synchronization, and global, which can cause contention in applications that run several ZooKeeper clients.

We now synchronize on outgoingQueue which is both local to a ClientCnxn's instance and stable.

Author: Sylvain Wallez <sylvain@bluxte.net>

Reviewers: maoling <maoling@apache.org>, Mohammad Arshad <arshad@apache.org>

Closes apache#1257 from swallez/ZOOKEEPER-3652 and squashes the following commits:

82e2cad [Sylvain Wallez] Instruct SpotBugs that we know what we're doing when synchronizing on outgoingQueue
b0bc03d [Sylvain Wallez] ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value

Co-authored-by: Sylvain Wallez <sylvain@bluxte.net>
anurag-harness pushed a commit to anurag-harness/zookeeper that referenced this pull request Jan 13, 2023
…le internal value

When packets are added to ClientCnxn's outgoing packet queue we ensure there's no conflict with an ongoing flush of that queue because of connection loss.

Synchronization used to be on the state field's value. This value is both not stable (its value changes over time), possibly causing improper synchronization, and global, which can cause contention in applications that run several ZooKeeper clients.

We now synchronize on outgoingQueue which is both local to a ClientCnxn's instance and stable.

Author: Sylvain Wallez <sylvain@bluxte.net>

Reviewers: maoling <maoling@apache.org>, Mohammad Arshad <arshad@apache.org>

Closes apache#1257 from swallez/ZOOKEEPER-3652 and squashes the following commits:

82e2cad [Sylvain Wallez] Instruct SpotBugs that we know what we're doing when synchronizing on outgoingQueue
b0bc03d [Sylvain Wallez] ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value
anurag-harness added a commit to anurag-harness/zookeeper that referenced this pull request Jan 13, 2023
…le internal value (#16)

When packets are added to ClientCnxn's outgoing packet queue we ensure there's no conflict with an ongoing flush of that queue because of connection loss.

Synchronization used to be on the state field's value. This value is both not stable (its value changes over time), possibly causing improper synchronization, and global, which can cause contention in applications that run several ZooKeeper clients.

We now synchronize on outgoingQueue which is both local to a ClientCnxn's instance and stable.

Author: Sylvain Wallez <sylvain@bluxte.net>

Reviewers: maoling <maoling@apache.org>, Mohammad Arshad <arshad@apache.org>

Closes apache#1257 from swallez/ZOOKEEPER-3652 and squashes the following commits:

82e2cad [Sylvain Wallez] Instruct SpotBugs that we know what we're doing when synchronizing on outgoingQueue
b0bc03d [Sylvain Wallez] ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value

Co-authored-by: Sylvain Wallez <sylvain@bluxte.net>
@laxmanprabhu
Copy link

The cleanUp method is also called by cleanAndNotifyState(). Is there a reason why cleanUp method call isn't synchronized in this code path as well.

When cleanAndNotifyState() calls cleanUp, the outgoingQueue is iterated without any synchronization. During this stage more callers can queue requests to the outgoingQueue. This causes the cleanUp method to keep iterating and possible take long time to complete.

desaikomal pushed a commit to linkedin/zookeeper that referenced this pull request Jun 17, 2023
…le internal value

When packets are added to ClientCnxn's outgoing packet queue we ensure there's no conflict with an ongoing flush of that queue because of connection loss.

Synchronization used to be on the state field's value. This value is both not stable (its value changes over time), possibly causing improper synchronization, and global, which can cause contention in applications that run several ZooKeeper clients.

We now synchronize on outgoingQueue which is both local to a ClientCnxn's instance and stable.

Author: Sylvain Wallez <sylvain@bluxte.net>

Reviewers: maoling <maoling@apache.org>, Mohammad Arshad <arshad@apache.org>

Closes apache#1257 from swallez/ZOOKEEPER-3652 and squashes the following commits:

82e2cad [Sylvain Wallez] Instruct SpotBugs that we know what we're doing when synchronizing on outgoingQueue
b0bc03d [Sylvain Wallez] ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value

(cherry picked from commit 91e0520)
Signed-off-by: Mohammad Arshad <arshad@apache.org>
desaikomal pushed a commit to linkedin/zookeeper that referenced this pull request Jun 27, 2023
…le internal value

When packets are added to ClientCnxn's outgoing packet queue we ensure there's no conflict with an ongoing flush of that queue because of connection loss.

Synchronization used to be on the state field's value. This value is both not stable (its value changes over time), possibly causing improper synchronization, and global, which can cause contention in applications that run several ZooKeeper clients.

We now synchronize on outgoingQueue which is both local to a ClientCnxn's instance and stable.

Author: Sylvain Wallez <sylvain@bluxte.net>

Reviewers: maoling <maoling@apache.org>, Mohammad Arshad <arshad@apache.org>

Closes apache#1257 from swallez/ZOOKEEPER-3652 and squashes the following commits:

82e2cad [Sylvain Wallez] Instruct SpotBugs that we know what we're doing when synchronizing on outgoingQueue
b0bc03d [Sylvain Wallez] ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value

(cherry picked from commit 91e0520)
Signed-off-by: Mohammad Arshad <arshad@apache.org>
anmolnar pushed a commit to anmolnar/zookeeper that referenced this pull request May 21, 2024
…le internal value

When packets are added to ClientCnxn's outgoing packet queue we ensure there's no conflict with an ongoing flush of that queue because of connection loss.

Synchronization used to be on the state field's value. This value is both not stable (its value changes over time), possibly causing improper synchronization, and global, which can cause contention in applications that run several ZooKeeper clients.

We now synchronize on outgoingQueue which is both local to a ClientCnxn's instance and stable.

Author: Sylvain Wallez <sylvainbluxte.net>

Reviewers: maoling <maolingapache.org>, Mohammad Arshad <arshadapache.org>

Closes apache#1257 from swallez/ZOOKEEPER-3652 and squashes the following commits:

82e2cad [Sylvain Wallez] Instruct SpotBugs that we know what we're doing when synchronizing on outgoingQueue
b0bc03d [Sylvain Wallez] ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value

(cherry picked from commit 91e0520)

Author: Sylvain Wallez <sylvain@bluxte.net>
Author: Mate Szalay-Beko <symat@apache.org>

Reviewers: Sylvain Wallez <sylvain@bluxte.net>, Mohammad Arshad <arshad@apache.org>, maoling <maoling@apache.org>

Closes apache#1850 from symat/ZOOKEEPER-3652-branch-3.5 and squashes the following commits:

5cd29db [Mate Szalay-Beko] remove formatting changes
e925265 [Sylvain Wallez] ZOOKEEPER-3652: Synchronize ClientCnxn outgoing queue flush on a stable internal value

(cherry picked from commit 2610a19)
Change-Id: Ib6317fd320e6eedfdaecd0db2e073cb2c92c9752
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants