curator-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Shiliang Cao (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (CURATOR-233) Bug in double barrier
Date Mon, 25 Apr 2016 03:11:12 GMT

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

Shiliang Cao commented on CURATOR-233:
--------------------------------------

I did some test about the codes before modifying and after modifying, unfortunately the result
shows this double barrier can still not act as our expectation.

Old codes' problem: 
Timeout value is invalid, if one thread does not leave, other threads will not leave either.
Finally, when the last thread leave, it leave with true while others leave with false. It's
definitely not our expectation.

New codes problem:
The behaviors are uncertain but apparently not correct, I set 3 threads, thread1 sleep 10
secondes after entering, thread2 and thread3 wait 5 seconds to leave. I think the design should
be all return false, but actually they didn't.

Here're the test codes in case you need:
// ===============================================
package curator_test;

import java.util.concurrent.TimeUnit;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DoubleBarrierTimeoutTest {
    private static final String CONNECTION_STRING = "localhost:2181";
    private static final RetryPolicy RETRY_POLICY = new ExponentialBackoffRetry(1000, 3);
    private static final CuratorFramework CLIENT = CuratorFrameworkFactory.newClient(CONNECTION_STRING,
RETRY_POLICY);
    private static final String PATH = "/barrier";
    private static final Logger log = LoggerFactory.getLogger(DistributedDoubleBarrierTest.class);
    static {
        CLIENT.start();
    }
    public static void main(String[] args) {
        int num = 3;
        Thread t1 = new Thread(new Worker1(CLIENT, PATH, num));
        t1.setName("Worker1");
        Thread t2 = new Thread(new Worker2(CLIENT, PATH, num));
        t2.setName("Worker2");
        Thread t3 = new Thread(new Worker3(CLIENT, PATH, num));
        t3.setName("Worker3");
        t1.start();
        t2.start();
        t3.start();
    }
}

class Worker {
    DistributedDoubleBarrier barrier;
    protected static final Logger log = LoggerFactory.getLogger(Worker.class);
    public Worker(CuratorFramework client, String barrierPath, int num) {
        barrier = new DistributedDoubleBarrier(client, barrierPath, num);
    }
}

class Worker1 extends Worker implements Runnable {

    public Worker1(CuratorFramework client, String barrierPath, int num) {
        super(client, barrierPath, num);
    }

    public void run() {
        try {
            barrier.enter();
            // sleep 10 seconds
            Thread.sleep(10 * 1000);
            boolean leave = barrier.leave(5, TimeUnit.SECONDS); // wait 5 seconds to leave
            log.info("Worker1 left with {}", leave);
        } catch (Exception e) {
            log.error("Error happened: ", e);
        }
    }
}


class Worker2 extends Worker implements Runnable {

    public Worker2(CuratorFramework client, String barrierPath, int num) {
        super(client, barrierPath, num);
    }

    public void run() {
        try {
            barrier.enter();
            boolean leave = barrier.leave(5, TimeUnit.SECONDS); // wait 5 seconds to leave
            log.info("Worker2 left with {}", leave);
        } catch (Exception e) {
            log.error("Error happened: ", e);
        }
    }
}

class Worker3 extends Worker implements Runnable {

    public Worker3(CuratorFramework client, String barrierPath, int num) {
        super(client, barrierPath, num);
    }

    public void run() {
        try {
            barrier.enter();
            boolean leave = barrier.leave(5, TimeUnit.SECONDS); // wait 5 seconds to leave
            log.info("Worker3 left with {}", leave);
        } catch (Exception e) {
            log.error("Error happened: ", e);
        }
    }
}
// ===============================================


> Bug in double barrier
> ---------------------
>
>                 Key: CURATOR-233
>                 URL: https://issues.apache.org/jira/browse/CURATOR-233
>             Project: Apache Curator
>          Issue Type: Bug
>          Components: Recipes
>    Affects Versions: 2.8.0
>            Reporter: J D
>            Assignee: Mike Drob
>             Fix For: 2.10.1, 3.1.1
>
>         Attachments: DoubleBarrierClient.java, DoubleBarrierTester.java
>
>
> Hi,
> I think I discovered a bug in the internalLeave method of the double barrier implementation.
> When a client is told to leave the barrier after maxWait it does not do so. A flag is
set but the client does not leave the barrier, instead it keeps iterating through the control
loop and drives CPU usage to 100%.
> I have attached an example.
> Best regards
> Lianro



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message