You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@curator.apache.org by "Kim Jaechang (JIRA)" <ji...@apache.org> on 2019/06/05 16:29:00 UTC

[jira] [Comment Edited] (CURATOR-527) Concurrency issue in LockInternals

    [ https://issues.apache.org/jira/browse/CURATOR-527?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16856836#comment-16856836 ] 

Kim Jaechang edited comment on CURATOR-527 at 6/5/19 4:28 PM:
--------------------------------------------------------------

[~randgalt] The case I said was node deleted after getData() called and before wait() called. 
I checked from thread dump that localvariable for lock-759(previousSequencePath) and lock-760(ourPath) exist but in zookeeper, only lock-760 exist.

I am sorry I can't upload my original test code because current project is not open-source project.
I'll leave pseudo code for my case. multiple instances was running concurrently.
{code:java}
  abstract class BaseWatcher implements CuratorWatcher {
    private InterProcessMutex lock;
    private final String objectPath = "/object";
    private final String lockPath = "/lock";
    private String namespace;

    BaseWatcher() {
      this.lock = new InterProcessMutex(this.zooKeeperClient, this.namespace + lockPath);
    }

    @Override
    public abstract void process(WatchedEvent watchedEvent);

    protected void lock() throws Exception {
      this.lock.acquire();
    }

    protected void unlock() throws Exception {
      if (this.lock.isAcquiredInThisProcess()) {
        this.lock.release();
      }
    }

    protected void registerWatcher(CuratorWatcher watcher, boolean isWatcher2) throws Exception {
      if (isWatcher2) {
        this.zooKeeperClient.checkExists().usingWatcher(watcher).forPath(namespace + PathforWatcher2);
      } else {
        this.zooKeeperClient.checkExists().usingWatcher(watcher).forPath(namespace + objectPath);
      }
    }

    protected void updateObject(Byte[] data){
      this.zooKeeperClient.setData().forPath(namespace + objectPath, data);
    }
  }

  class Watcher1 extends BaseWatcher {

    @Override
    public void process(WatchedEvent watchedEvent) {
      try {
        super.lock();
        registerWatcher(this, false);
        super.unlock();
      } 
    }
  }

  class Watcher2 extends BaseWatcher {

    @Override
    public void process(WatchedEvent watchedEvent) {
      try {
        super.lock();
        super.updateObject(contents);
        super.unlock();
        super.registerWatcher(this, true);
      }
    }
  }

{code}



was (Author: jc5201):
[~randgalt] The case I said was node deleted after getData() called and before wait() called. 
I checked from thread dump that localvariable for lock-759(previousSequencePath) and lock-760(ourPath) exist but in zookeeper, only lock-760 exist.

I am sorry I can't upload my original test code because current project is not open-source project.
I'll leave pseudo code for my case. multiple instances was running concurrently.
{code:java}
  private abstract class BaseWatcher implements CuratorWatcher {
    private InterProcessMutex lock;
    private final String objectPath = "/object";
    private final String lockPath = "/lock";
    private String namespace;

    BaseWatcher() {
      this.lock = new InterProcessMutex(this.zooKeeperClient, this.namespace + lockPath);
    }

    @Override
    public abstract void process(WatchedEvent watchedEvent);

    protected void lock() throws Exception {
      this.lock.acquire();
    }

    protected void unlock() throws Exception {
      if (this.lock.isAcquiredInThisProcess()) {
        this.lock.release();
      }
    }

    protected void registerWatcher(CuratorWatcher watcher, boolean isWatcher2) throws Exception {
      if (isWatcher2) {
        this.zooKeeperClient.checkExists().usingWatcher(watcher).forPath(namespace + PathforWatcher2);
      } else {
        this.zooKeeperClient.checkExists().usingWatcher(watcher).forPath(namespace + objectPath);
      }
    }

    protected void updateObject(Byte[] data){
      this.zooKeeperClient.setData().forPath(namespace + objectPath, data);
    }
  }

  private class Watcher1 extends BaseWatcher {

    @Override
    public void process(WatchedEvent watchedEvent) {
      try {
        super.lock();
        registerWatcher(this, false);
        super.unlock();
      } 
    }
  }

  private class Watcher2 extends BaseWatcher {

    @Override
    public void process(WatchedEvent watchedEvent) {
      try {
        super.lock();
        super.updateObject(contents);
        super.unlock();
        super.registerWatcher(this, true);
      }
    }
  }

{code}


> Concurrency issue in LockInternals
> ----------------------------------
>
>                 Key: CURATOR-527
>                 URL: https://issues.apache.org/jira/browse/CURATOR-527
>             Project: Apache Curator
>          Issue Type: Bug
>          Components: Recipes
>    Affects Versions: 2.12.0
>         Environment: Curator 2.12.0
> zookeeper 3.4.14
>            Reporter: Kim Jaechang
>            Priority: Major
>
> I'm using InterProcessMutex and InterProcessMutex often failed to acquire lock.
> In LockInternals.internalLockLoop(), watcher is registered to zookeeper and call wait() like below
> {code:java}
> client.getData().usingWatcher(watcher).forPath(previousSequencePath);
> if ( millisToWait != null )
> {
>     millisToWait -= (System.currentTimeMillis() - startMillis);
>     startMillis = System.currentTimeMillis();
>     if ( millisToWait <= 0 )
>     {
>         doDelete = true;    // timed out - delete our node
>         break;
>     }
>     wait(millisToWait);
> }
> else
> {
>     wait();
> }
> {code}
> In my case, my program is waiting previousSequencePath=_c_f290140d-9856-42ad-b9bf-348ffc086062-lock-0000000759 to be deleted.
> But _c_f290140d-9856-42ad-b9bf-348ffc086062-lock-0000000759 is deleted between client.getData() and wait().
> if _c_f290140d-9856-42ad-b9bf-348ffc086062-lock-0000000759 is deleted when 
> client.getData().usingWatcher(watcher).forPath(previousSequencePath) is called, it will throw Exception but it was exist at that time.
> I'm using Curator 2.12.0 but latest version seems to have same issue.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)