You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@zookeeper.apache.org by "yynil (JIRA)" <ji...@apache.org> on 2011/07/19 18:51:01 UTC

[jira] [Created] (ZOOKEEPER-1128) Recipe wrong for Lock process.

Recipe wrong for Lock process.
------------------------------

                 Key: ZOOKEEPER-1128
                 URL: https://issues.apache.org/jira/browse/ZOOKEEPER-1128
             Project: ZooKeeper
          Issue Type: Bug
          Components: recipes
    Affects Versions: 3.3.3
            Reporter: yynil


http://zookeeper.apache.org/doc/trunk/recipes.html
The current recipe for Lock has the wrong process.
Specifically, for the 
"4. The client calls exists( ) with the watch flag set on the path in the lock directory with the next lowest sequence number."
It shouldn't be the "the next lowest sequence number". It should be the "current lowest path". 

If you're gonna use "the next lowest sequence number", you'll never wait for the lock possession.

The following is the test code:

{code:title=LockTest.java|borderStyle=solid}
        ACL acl = new ACL(Perms.ALL, new Id("10.0.0.0/8", "1"));
        List<ACL> acls = new ArrayList<ACL>();
        acls.add(acl);
        String connectStr = "localhost:2181";
        final Semaphore sem = new Semaphore(0);
        ZooKeeper zooKeeper = new ZooKeeper(connectStr, 1000 * 30, new Watcher() {

            @Override
            public void process(WatchedEvent event) {
                System.out.println("eventType:" + event.getType());
                System.out.println("keeperState:" + event.getState());
                if (event.getType() == Event.EventType.None) {
                    if (event.getState() == Event.KeeperState.SyncConnected) {
                        sem.release();
                    }
                }
            }
        });
        System.out.println("state:" + zooKeeper.getState());
        System.out.println("Waiting for the state to be connected");
        try {
            sem.acquire();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
        System.out.println("Now state:" + zooKeeper.getState());

        String directory = "/_locknode_";
        Stat stat = zooKeeper.exists(directory, false);
        if (stat == null) {
            zooKeeper.create(directory, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }
        String prefix = directory + "/lock-";
        String path = zooKeeper.create(prefix, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        System.out.println("Create the path for " + path);
        while (true) {
            List<String> children = zooKeeper.getChildren(directory, false);
            Collections.sort(children);
            System.out.println("The whole lock size is " + children.size());
            String lowestPath = children.get(0);
            DecimalFormat df = new DecimalFormat("0000000000");
            String currentSuffix = lowestPath.substring("lock-".length());
            System.out.println("CurrentSuffix is " + currentSuffix);
            int intIndex = Integer.parseInt(currentSuffix);

            if (path.equals(directory + "/" + lowestPath)) {
                //I've got the lock and release it
                System.out.println("I've got the lock at " + new Date());
                System.out.println("next index is " + intIndex);
                Thread.sleep(10000);
                System.out.println("After sleep 3 seconds, I'm gonna release the lock");
                zooKeeper.delete(path, -1);
                break;
            }
            final Semaphore wakeupSem = new Semaphore(0);
            stat = zooKeeper.exists(directory + "/" + lowestPath, new Watcher() {

                @Override
                public void process(WatchedEvent event) {
                    System.out.println("Event is " + event.getType());
                    System.out.println("State is " + event.getState());
                    if (event.getType() == Event.EventType.NodeDeleted) {
                        wakeupSem.release();
                    }
                }
            });
            if (stat != null) {
                System.out.println("Waiting for the delete of ");
                wakeupSem.acquire();
            } else {
                System.out.println("Continue to seek");
            }
        }
{code} 

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

[jira] [Updated] (ZOOKEEPER-1128) Recipe wrong for Lock process.

Posted by "Larry G. Rapp (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/ZOOKEEPER-1128?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Larry G. Rapp updated ZOOKEEPER-1128:
-------------------------------------

    Attachment: singulair.html
    
> Recipe wrong for Lock process.
> ------------------------------
>
>                 Key: ZOOKEEPER-1128
>                 URL: https://issues.apache.org/jira/browse/ZOOKEEPER-1128
>             Project: ZooKeeper
>          Issue Type: Bug
>          Components: recipes
>    Affects Versions: 3.3.3
>            Reporter: yynil
>         Attachments: singulair.html
>
>
> http://zookeeper.apache.org/doc/trunk/recipes.html
> The current recipe for Lock has the wrong process.
> Specifically, for the 
> "4. The client calls exists( ) with the watch flag set on the path in the lock directory with the next lowest sequence number."
> It shouldn't be the "the next lowest sequence number". It should be the "current lowest path". 
> If you're gonna use "the next lowest sequence number", you'll never wait for the lock possession.
> The following is the test code:
> {code:title=LockTest.java|borderStyle=solid}
>         ACL acl = new ACL(Perms.ALL, new Id("10.0.0.0/8", "1"));
>         List<ACL> acls = new ArrayList<ACL>();
>         acls.add(acl);
>         String connectStr = "localhost:2181";
>         final Semaphore sem = new Semaphore(0);
>         ZooKeeper zooKeeper = new ZooKeeper(connectStr, 1000 * 30, new Watcher() {
>             @Override
>             public void process(WatchedEvent event) {
>                 System.out.println("eventType:" + event.getType());
>                 System.out.println("keeperState:" + event.getState());
>                 if (event.getType() == Event.EventType.None) {
>                     if (event.getState() == Event.KeeperState.SyncConnected) {
>                         sem.release();
>                     }
>                 }
>             }
>         });
>         System.out.println("state:" + zooKeeper.getState());
>         System.out.println("Waiting for the state to be connected");
>         try {
>             sem.acquire();
>         } catch (InterruptedException ex) {
>             ex.printStackTrace();
>         }
>         System.out.println("Now state:" + zooKeeper.getState());
>         String directory = "/_locknode_";
>         Stat stat = zooKeeper.exists(directory, false);
>         if (stat == null) {
>             zooKeeper.create(directory, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
>         }
>         String prefix = directory + "/lock-";
>         String path = zooKeeper.create(prefix, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
>         System.out.println("Create the path for " + path);
>         while (true) {
>             List<String> children = zooKeeper.getChildren(directory, false);
>             Collections.sort(children);
>             System.out.println("The whole lock size is " + children.size());
>             String lowestPath = children.get(0);
>             DecimalFormat df = new DecimalFormat("0000000000");
>             String currentSuffix = lowestPath.substring("lock-".length());
>             System.out.println("CurrentSuffix is " + currentSuffix);
>             int intIndex = Integer.parseInt(currentSuffix);
>             if (path.equals(directory + "/" + lowestPath)) {
>                 //I've got the lock and release it
>                 System.out.println("I've got the lock at " + new Date());
>                 System.out.println("next index is " + intIndex);
>                 Thread.sleep(10000);
>                 System.out.println("After sleep 3 seconds, I'm gonna release the lock");
>                 zooKeeper.delete(path, -1);
>                 break;
>             }
>             final Semaphore wakeupSem = new Semaphore(0);
>             stat = zooKeeper.exists(directory + "/" + lowestPath, new Watcher() {
>                 @Override
>                 public void process(WatchedEvent event) {
>                     System.out.println("Event is " + event.getType());
>                     System.out.println("State is " + event.getState());
>                     if (event.getType() == Event.EventType.NodeDeleted) {
>                         wakeupSem.release();
>                     }
>                 }
>             });
>             if (stat != null) {
>                 System.out.println("Waiting for the delete of ");
>                 wakeupSem.acquire();
>             } else {
>                 System.out.println("Continue to seek");
>             }
>         }
> {code} 

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

[jira] [Resolved] (ZOOKEEPER-1128) Recipe wrong for Lock process.

Posted by "yynil (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/ZOOKEEPER-1128?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

yynil resolved ZOOKEEPER-1128.
------------------------------

    Resolution: Fixed

With Hunt's comments, it's clear to me. I feel this issue resolved with the explanation. It will be good to add these comments to the tutorial to help the newbies like me. 

> Recipe wrong for Lock process.
> ------------------------------
>
>                 Key: ZOOKEEPER-1128
>                 URL: https://issues.apache.org/jira/browse/ZOOKEEPER-1128
>             Project: ZooKeeper
>          Issue Type: Bug
>          Components: recipes
>    Affects Versions: 3.3.3
>            Reporter: yynil
>
> http://zookeeper.apache.org/doc/trunk/recipes.html
> The current recipe for Lock has the wrong process.
> Specifically, for the 
> "4. The client calls exists( ) with the watch flag set on the path in the lock directory with the next lowest sequence number."
> It shouldn't be the "the next lowest sequence number". It should be the "current lowest path". 
> If you're gonna use "the next lowest sequence number", you'll never wait for the lock possession.
> The following is the test code:
> {code:title=LockTest.java|borderStyle=solid}
>         ACL acl = new ACL(Perms.ALL, new Id("10.0.0.0/8", "1"));
>         List<ACL> acls = new ArrayList<ACL>();
>         acls.add(acl);
>         String connectStr = "localhost:2181";
>         final Semaphore sem = new Semaphore(0);
>         ZooKeeper zooKeeper = new ZooKeeper(connectStr, 1000 * 30, new Watcher() {
>             @Override
>             public void process(WatchedEvent event) {
>                 System.out.println("eventType:" + event.getType());
>                 System.out.println("keeperState:" + event.getState());
>                 if (event.getType() == Event.EventType.None) {
>                     if (event.getState() == Event.KeeperState.SyncConnected) {
>                         sem.release();
>                     }
>                 }
>             }
>         });
>         System.out.println("state:" + zooKeeper.getState());
>         System.out.println("Waiting for the state to be connected");
>         try {
>             sem.acquire();
>         } catch (InterruptedException ex) {
>             ex.printStackTrace();
>         }
>         System.out.println("Now state:" + zooKeeper.getState());
>         String directory = "/_locknode_";
>         Stat stat = zooKeeper.exists(directory, false);
>         if (stat == null) {
>             zooKeeper.create(directory, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
>         }
>         String prefix = directory + "/lock-";
>         String path = zooKeeper.create(prefix, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
>         System.out.println("Create the path for " + path);
>         while (true) {
>             List<String> children = zooKeeper.getChildren(directory, false);
>             Collections.sort(children);
>             System.out.println("The whole lock size is " + children.size());
>             String lowestPath = children.get(0);
>             DecimalFormat df = new DecimalFormat("0000000000");
>             String currentSuffix = lowestPath.substring("lock-".length());
>             System.out.println("CurrentSuffix is " + currentSuffix);
>             int intIndex = Integer.parseInt(currentSuffix);
>             if (path.equals(directory + "/" + lowestPath)) {
>                 //I've got the lock and release it
>                 System.out.println("I've got the lock at " + new Date());
>                 System.out.println("next index is " + intIndex);
>                 Thread.sleep(10000);
>                 System.out.println("After sleep 3 seconds, I'm gonna release the lock");
>                 zooKeeper.delete(path, -1);
>                 break;
>             }
>             final Semaphore wakeupSem = new Semaphore(0);
>             stat = zooKeeper.exists(directory + "/" + lowestPath, new Watcher() {
>                 @Override
>                 public void process(WatchedEvent event) {
>                     System.out.println("Event is " + event.getType());
>                     System.out.println("State is " + event.getState());
>                     if (event.getType() == Event.EventType.NodeDeleted) {
>                         wakeupSem.release();
>                     }
>                 }
>             });
>             if (stat != null) {
>                 System.out.println("Waiting for the delete of ");
>                 wakeupSem.acquire();
>             } else {
>                 System.out.println("Continue to seek");
>             }
>         }
> {code} 

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

[jira] [Commented] (ZOOKEEPER-1128) Recipe wrong for Lock process.

Posted by "yynil (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/ZOOKEEPER-1128?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13072135#comment-13072135 ] 

yynil commented on ZOOKEEPER-1128:
----------------------------------

ops, I got it.
I just misunderstood the term "the next lowest sequence number". 
It means "next" to MY number while is not "next" to the current lock number.
It solves my problem and it's way better than "current lock" solution I'm using now.

But some more suggestion is to just add your comments here in the tutorial. I don't know if I'm the only one to misunderstand it. 
 




> Recipe wrong for Lock process.
> ------------------------------
>
>                 Key: ZOOKEEPER-1128
>                 URL: https://issues.apache.org/jira/browse/ZOOKEEPER-1128
>             Project: ZooKeeper
>          Issue Type: Bug
>          Components: recipes
>    Affects Versions: 3.3.3
>            Reporter: yynil
>
> http://zookeeper.apache.org/doc/trunk/recipes.html
> The current recipe for Lock has the wrong process.
> Specifically, for the 
> "4. The client calls exists( ) with the watch flag set on the path in the lock directory with the next lowest sequence number."
> It shouldn't be the "the next lowest sequence number". It should be the "current lowest path". 
> If you're gonna use "the next lowest sequence number", you'll never wait for the lock possession.
> The following is the test code:
> {code:title=LockTest.java|borderStyle=solid}
>         ACL acl = new ACL(Perms.ALL, new Id("10.0.0.0/8", "1"));
>         List<ACL> acls = new ArrayList<ACL>();
>         acls.add(acl);
>         String connectStr = "localhost:2181";
>         final Semaphore sem = new Semaphore(0);
>         ZooKeeper zooKeeper = new ZooKeeper(connectStr, 1000 * 30, new Watcher() {
>             @Override
>             public void process(WatchedEvent event) {
>                 System.out.println("eventType:" + event.getType());
>                 System.out.println("keeperState:" + event.getState());
>                 if (event.getType() == Event.EventType.None) {
>                     if (event.getState() == Event.KeeperState.SyncConnected) {
>                         sem.release();
>                     }
>                 }
>             }
>         });
>         System.out.println("state:" + zooKeeper.getState());
>         System.out.println("Waiting for the state to be connected");
>         try {
>             sem.acquire();
>         } catch (InterruptedException ex) {
>             ex.printStackTrace();
>         }
>         System.out.println("Now state:" + zooKeeper.getState());
>         String directory = "/_locknode_";
>         Stat stat = zooKeeper.exists(directory, false);
>         if (stat == null) {
>             zooKeeper.create(directory, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
>         }
>         String prefix = directory + "/lock-";
>         String path = zooKeeper.create(prefix, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
>         System.out.println("Create the path for " + path);
>         while (true) {
>             List<String> children = zooKeeper.getChildren(directory, false);
>             Collections.sort(children);
>             System.out.println("The whole lock size is " + children.size());
>             String lowestPath = children.get(0);
>             DecimalFormat df = new DecimalFormat("0000000000");
>             String currentSuffix = lowestPath.substring("lock-".length());
>             System.out.println("CurrentSuffix is " + currentSuffix);
>             int intIndex = Integer.parseInt(currentSuffix);
>             if (path.equals(directory + "/" + lowestPath)) {
>                 //I've got the lock and release it
>                 System.out.println("I've got the lock at " + new Date());
>                 System.out.println("next index is " + intIndex);
>                 Thread.sleep(10000);
>                 System.out.println("After sleep 3 seconds, I'm gonna release the lock");
>                 zooKeeper.delete(path, -1);
>                 break;
>             }
>             final Semaphore wakeupSem = new Semaphore(0);
>             stat = zooKeeper.exists(directory + "/" + lowestPath, new Watcher() {
>                 @Override
>                 public void process(WatchedEvent event) {
>                     System.out.println("Event is " + event.getType());
>                     System.out.println("State is " + event.getState());
>                     if (event.getType() == Event.EventType.NodeDeleted) {
>                         wakeupSem.release();
>                     }
>                 }
>             });
>             if (stat != null) {
>                 System.out.println("Waiting for the delete of ");
>                 wakeupSem.acquire();
>             } else {
>                 System.out.println("Continue to seek");
>             }
>         }
> {code} 

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

[jira] [Commented] (ZOOKEEPER-1128) Recipe wrong for Lock process.

Posted by "Patrick Hunt (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/ZOOKEEPER-1128?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13072213#comment-13072213 ] 

Patrick Hunt commented on ZOOKEEPER-1128:
-----------------------------------------

Updating the docs to clarify this sounds reasonable to me. I'd encourage you to create a new jira for this (and a patch would be great too! :-) ). Perhaps as an example similar to what I gave in my comment? thanks.


> Recipe wrong for Lock process.
> ------------------------------
>
>                 Key: ZOOKEEPER-1128
>                 URL: https://issues.apache.org/jira/browse/ZOOKEEPER-1128
>             Project: ZooKeeper
>          Issue Type: Bug
>          Components: recipes
>    Affects Versions: 3.3.3
>            Reporter: yynil
>
> http://zookeeper.apache.org/doc/trunk/recipes.html
> The current recipe for Lock has the wrong process.
> Specifically, for the 
> "4. The client calls exists( ) with the watch flag set on the path in the lock directory with the next lowest sequence number."
> It shouldn't be the "the next lowest sequence number". It should be the "current lowest path". 
> If you're gonna use "the next lowest sequence number", you'll never wait for the lock possession.
> The following is the test code:
> {code:title=LockTest.java|borderStyle=solid}
>         ACL acl = new ACL(Perms.ALL, new Id("10.0.0.0/8", "1"));
>         List<ACL> acls = new ArrayList<ACL>();
>         acls.add(acl);
>         String connectStr = "localhost:2181";
>         final Semaphore sem = new Semaphore(0);
>         ZooKeeper zooKeeper = new ZooKeeper(connectStr, 1000 * 30, new Watcher() {
>             @Override
>             public void process(WatchedEvent event) {
>                 System.out.println("eventType:" + event.getType());
>                 System.out.println("keeperState:" + event.getState());
>                 if (event.getType() == Event.EventType.None) {
>                     if (event.getState() == Event.KeeperState.SyncConnected) {
>                         sem.release();
>                     }
>                 }
>             }
>         });
>         System.out.println("state:" + zooKeeper.getState());
>         System.out.println("Waiting for the state to be connected");
>         try {
>             sem.acquire();
>         } catch (InterruptedException ex) {
>             ex.printStackTrace();
>         }
>         System.out.println("Now state:" + zooKeeper.getState());
>         String directory = "/_locknode_";
>         Stat stat = zooKeeper.exists(directory, false);
>         if (stat == null) {
>             zooKeeper.create(directory, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
>         }
>         String prefix = directory + "/lock-";
>         String path = zooKeeper.create(prefix, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
>         System.out.println("Create the path for " + path);
>         while (true) {
>             List<String> children = zooKeeper.getChildren(directory, false);
>             Collections.sort(children);
>             System.out.println("The whole lock size is " + children.size());
>             String lowestPath = children.get(0);
>             DecimalFormat df = new DecimalFormat("0000000000");
>             String currentSuffix = lowestPath.substring("lock-".length());
>             System.out.println("CurrentSuffix is " + currentSuffix);
>             int intIndex = Integer.parseInt(currentSuffix);
>             if (path.equals(directory + "/" + lowestPath)) {
>                 //I've got the lock and release it
>                 System.out.println("I've got the lock at " + new Date());
>                 System.out.println("next index is " + intIndex);
>                 Thread.sleep(10000);
>                 System.out.println("After sleep 3 seconds, I'm gonna release the lock");
>                 zooKeeper.delete(path, -1);
>                 break;
>             }
>             final Semaphore wakeupSem = new Semaphore(0);
>             stat = zooKeeper.exists(directory + "/" + lowestPath, new Watcher() {
>                 @Override
>                 public void process(WatchedEvent event) {
>                     System.out.println("Event is " + event.getType());
>                     System.out.println("State is " + event.getState());
>                     if (event.getType() == Event.EventType.NodeDeleted) {
>                         wakeupSem.release();
>                     }
>                 }
>             });
>             if (stat != null) {
>                 System.out.println("Waiting for the delete of ");
>                 wakeupSem.acquire();
>             } else {
>                 System.out.println("Continue to seek");
>             }
>         }
> {code} 

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

[jira] [Commented] (ZOOKEEPER-1128) Recipe wrong for Lock process.

Posted by "Patrick Hunt (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/ZOOKEEPER-1128?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13071888#comment-13071888 ] 

Patrick Hunt commented on ZOOKEEPER-1128:
-----------------------------------------

bq. It shouldn't be the "the next lowest sequence number". It should be the "current lowest path".

this seems incorrect to me as the intent is to eliminate a herd effect on write locking. Using the "current lowest path" would result in all waiting writers waking up each time the lock is free'd. By using the next lowest this doesn't happen

A creates write-1 and holds lock
B creates write-2, watches 1 (next lowest to it's own write-2)
C creates write-3, watches 2
A releases the lock
B wakes up
B releases lock
C wakes up

If B drops out before A releases the lock C will wake up and see that A still has the lock.

Is there a particular scenario that you can point out not handled here?


> Recipe wrong for Lock process.
> ------------------------------
>
>                 Key: ZOOKEEPER-1128
>                 URL: https://issues.apache.org/jira/browse/ZOOKEEPER-1128
>             Project: ZooKeeper
>          Issue Type: Bug
>          Components: recipes
>    Affects Versions: 3.3.3
>            Reporter: yynil
>
> http://zookeeper.apache.org/doc/trunk/recipes.html
> The current recipe for Lock has the wrong process.
> Specifically, for the 
> "4. The client calls exists( ) with the watch flag set on the path in the lock directory with the next lowest sequence number."
> It shouldn't be the "the next lowest sequence number". It should be the "current lowest path". 
> If you're gonna use "the next lowest sequence number", you'll never wait for the lock possession.
> The following is the test code:
> {code:title=LockTest.java|borderStyle=solid}
>         ACL acl = new ACL(Perms.ALL, new Id("10.0.0.0/8", "1"));
>         List<ACL> acls = new ArrayList<ACL>();
>         acls.add(acl);
>         String connectStr = "localhost:2181";
>         final Semaphore sem = new Semaphore(0);
>         ZooKeeper zooKeeper = new ZooKeeper(connectStr, 1000 * 30, new Watcher() {
>             @Override
>             public void process(WatchedEvent event) {
>                 System.out.println("eventType:" + event.getType());
>                 System.out.println("keeperState:" + event.getState());
>                 if (event.getType() == Event.EventType.None) {
>                     if (event.getState() == Event.KeeperState.SyncConnected) {
>                         sem.release();
>                     }
>                 }
>             }
>         });
>         System.out.println("state:" + zooKeeper.getState());
>         System.out.println("Waiting for the state to be connected");
>         try {
>             sem.acquire();
>         } catch (InterruptedException ex) {
>             ex.printStackTrace();
>         }
>         System.out.println("Now state:" + zooKeeper.getState());
>         String directory = "/_locknode_";
>         Stat stat = zooKeeper.exists(directory, false);
>         if (stat == null) {
>             zooKeeper.create(directory, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
>         }
>         String prefix = directory + "/lock-";
>         String path = zooKeeper.create(prefix, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
>         System.out.println("Create the path for " + path);
>         while (true) {
>             List<String> children = zooKeeper.getChildren(directory, false);
>             Collections.sort(children);
>             System.out.println("The whole lock size is " + children.size());
>             String lowestPath = children.get(0);
>             DecimalFormat df = new DecimalFormat("0000000000");
>             String currentSuffix = lowestPath.substring("lock-".length());
>             System.out.println("CurrentSuffix is " + currentSuffix);
>             int intIndex = Integer.parseInt(currentSuffix);
>             if (path.equals(directory + "/" + lowestPath)) {
>                 //I've got the lock and release it
>                 System.out.println("I've got the lock at " + new Date());
>                 System.out.println("next index is " + intIndex);
>                 Thread.sleep(10000);
>                 System.out.println("After sleep 3 seconds, I'm gonna release the lock");
>                 zooKeeper.delete(path, -1);
>                 break;
>             }
>             final Semaphore wakeupSem = new Semaphore(0);
>             stat = zooKeeper.exists(directory + "/" + lowestPath, new Watcher() {
>                 @Override
>                 public void process(WatchedEvent event) {
>                     System.out.println("Event is " + event.getType());
>                     System.out.println("State is " + event.getState());
>                     if (event.getType() == Event.EventType.NodeDeleted) {
>                         wakeupSem.release();
>                     }
>                 }
>             });
>             if (stat != null) {
>                 System.out.println("Waiting for the delete of ");
>                 wakeupSem.acquire();
>             } else {
>                 System.out.println("Continue to seek");
>             }
>         }
> {code} 

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

[jira] [Commented] (ZOOKEEPER-1128) Recipe wrong for Lock process.

Posted by "Laxman (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/ZOOKEEPER-1128?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13069444#comment-13069444 ] 

Laxman commented on ZOOKEEPER-1128:
-----------------------------------

While implementing the lock recipe, I interpreted "the next lowest sequence number" correctly. I feel this phrase is not ambiguous and don't need to correct it.

Any suggestions?

> Recipe wrong for Lock process.
> ------------------------------
>
>                 Key: ZOOKEEPER-1128
>                 URL: https://issues.apache.org/jira/browse/ZOOKEEPER-1128
>             Project: ZooKeeper
>          Issue Type: Bug
>          Components: recipes
>    Affects Versions: 3.3.3
>            Reporter: yynil
>
> http://zookeeper.apache.org/doc/trunk/recipes.html
> The current recipe for Lock has the wrong process.
> Specifically, for the 
> "4. The client calls exists( ) with the watch flag set on the path in the lock directory with the next lowest sequence number."
> It shouldn't be the "the next lowest sequence number". It should be the "current lowest path". 
> If you're gonna use "the next lowest sequence number", you'll never wait for the lock possession.
> The following is the test code:
> {code:title=LockTest.java|borderStyle=solid}
>         ACL acl = new ACL(Perms.ALL, new Id("10.0.0.0/8", "1"));
>         List<ACL> acls = new ArrayList<ACL>();
>         acls.add(acl);
>         String connectStr = "localhost:2181";
>         final Semaphore sem = new Semaphore(0);
>         ZooKeeper zooKeeper = new ZooKeeper(connectStr, 1000 * 30, new Watcher() {
>             @Override
>             public void process(WatchedEvent event) {
>                 System.out.println("eventType:" + event.getType());
>                 System.out.println("keeperState:" + event.getState());
>                 if (event.getType() == Event.EventType.None) {
>                     if (event.getState() == Event.KeeperState.SyncConnected) {
>                         sem.release();
>                     }
>                 }
>             }
>         });
>         System.out.println("state:" + zooKeeper.getState());
>         System.out.println("Waiting for the state to be connected");
>         try {
>             sem.acquire();
>         } catch (InterruptedException ex) {
>             ex.printStackTrace();
>         }
>         System.out.println("Now state:" + zooKeeper.getState());
>         String directory = "/_locknode_";
>         Stat stat = zooKeeper.exists(directory, false);
>         if (stat == null) {
>             zooKeeper.create(directory, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
>         }
>         String prefix = directory + "/lock-";
>         String path = zooKeeper.create(prefix, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
>         System.out.println("Create the path for " + path);
>         while (true) {
>             List<String> children = zooKeeper.getChildren(directory, false);
>             Collections.sort(children);
>             System.out.println("The whole lock size is " + children.size());
>             String lowestPath = children.get(0);
>             DecimalFormat df = new DecimalFormat("0000000000");
>             String currentSuffix = lowestPath.substring("lock-".length());
>             System.out.println("CurrentSuffix is " + currentSuffix);
>             int intIndex = Integer.parseInt(currentSuffix);
>             if (path.equals(directory + "/" + lowestPath)) {
>                 //I've got the lock and release it
>                 System.out.println("I've got the lock at " + new Date());
>                 System.out.println("next index is " + intIndex);
>                 Thread.sleep(10000);
>                 System.out.println("After sleep 3 seconds, I'm gonna release the lock");
>                 zooKeeper.delete(path, -1);
>                 break;
>             }
>             final Semaphore wakeupSem = new Semaphore(0);
>             stat = zooKeeper.exists(directory + "/" + lowestPath, new Watcher() {
>                 @Override
>                 public void process(WatchedEvent event) {
>                     System.out.println("Event is " + event.getType());
>                     System.out.println("State is " + event.getState());
>                     if (event.getType() == Event.EventType.NodeDeleted) {
>                         wakeupSem.release();
>                     }
>                 }
>             });
>             if (stat != null) {
>                 System.out.println("Waiting for the delete of ");
>                 wakeupSem.acquire();
>             } else {
>                 System.out.println("Continue to seek");
>             }
>         }
> {code} 

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira