[ 
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

        

Reply via email to