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-2694:sync CLI command does not wait for result from server #823

Closed
wants to merge 7 commits into from

Conversation

maoling
Copy link
Member

@maoling maoling commented Feb 19, 2019

Copy link
Contributor

@anmolnar anmolnar left a comment

Choose a reason for hiding this comment

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

Overall the fix looks good to me, just having a few questions.

}
}, null);
} catch (IllegalArgumentException ex) {
latch.await();
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't it be safer to wait for some reasonable amount of time (30s) rather than waiting indefinitely?

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe it can be a parameter with a default of 30secs

} catch (IllegalArgumentException ex) {
latch.await();
out.println("Sync returned " + resultCode[0]);
} catch (IllegalArgumentException | InterruptedException ex) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you need to catch InterruptedException here?

Copy link
Member Author

Choose a reason for hiding this comment

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

latch.await needs this, my sweet IDEA help me do it.

Copy link
Contributor

@anmolnar anmolnar Mar 19, 2019

Choose a reason for hiding this comment

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

I don't think it's handled properly here. You basically swallowing and hiding it inside a MalformedPathException which is wrong.

}
}, null);
} catch (IllegalArgumentException ex) {
latch.await();
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe it can be a parameter with a default of 30secs

@@ -55,14 +57,18 @@ public CliCommand parse(String[] cmdArgs) throws CliParseException {
@Override
public boolean exec() throws CliException {
String path = args[1];
CountDownLatch latch = new CountDownLatch(1);
Copy link
Contributor

Choose a reason for hiding this comment

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

What about a more modern CompletableFuture?

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for mentioning this good option:CompletableFuture,but for issue,IMO,we don't need to kill a chicken with the sword:D

Copy link
Contributor

Choose a reason for hiding this comment

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

CompletableFuture has specifically been designed for scenarios like this. As far as I'm concerned. Let me check.

Copy link
Contributor

Choose a reason for hiding this comment

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

How about this?

    @Override
    public boolean exec() throws CliException {
        String path = args[1];
        CompletableFuture<Integer> cf = new CompletableFuture<>();

        try {
            zk.sync(path, new AsyncCallback.VoidCallback() {
                public void processResult(int rc, String path, Object ctx) {
                    cf.complete(rc);
                }
            }, null);

            try {
                int resultCode = cf.get(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS);
                out.println("Sync returned " + resultCode);
            } catch (TimeoutException ex) {
                out.println("Sync is timeout within " +  CONNECTION_TIMEOUT + " ms");
            }
        } catch (IllegalArgumentException | InterruptedException | ExecutionException ex) {
            throw new MalformedPathException(ex.getMessage());
        }

        return false;
    }

Copy link
Member Author

Choose a reason for hiding this comment

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

@anmolnar Great work. you are so sweet! it's very elegant especially when we want to transfer the result value.
Cc:Thanks @eolivelli for mentioning this good option:CompletableFuture again.

@@ -55,14 +57,18 @@ public CliCommand parse(String[] cmdArgs) throws CliParseException {
@Override
public boolean exec() throws CliException {
String path = args[1];
CountDownLatch latch = new CountDownLatch(1);
final int[] resultCode = new int[1];
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is an array necessary here? Wouldn't a plain integer be sufficient?

Copy link
Member Author

Choose a reason for hiding this comment

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

when use a plain integer, a anonymous Inner Class needs it to be modified with final ,then we cannot assignment and transfer the result outside.

@maoling maoling force-pushed the ZOOKEEPER-2694 branch 3 times, most recently from c219e8b to fe6bc5c Compare March 20, 2019 11:22
@maoling maoling closed this Mar 20, 2019
@maoling maoling reopened this Mar 20, 2019
Copy link
Contributor

@anmolnar anmolnar left a comment

Choose a reason for hiding this comment

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

+1 LGTM

@maoling
Copy link
Member Author

maoling commented Apr 3, 2019

ping @anmolnar

@anmolnar
Copy link
Contributor

anmolnar commented Apr 3, 2019

@phunt @eolivelli Would you like to take another look?

@@ -30,6 +35,7 @@

private static Options options = new Options();
private String[] args;
public static final int CONNECTION_TIMEOUT = 30000;//30s
Copy link
Contributor

Choose a reason for hiding this comment

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

What about 'SYNC_TIMEOUT' ?
It is not used for 'comnection'

Copy link
Member Author

Choose a reason for hiding this comment

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

+1

Copy link
Contributor

Choose a reason for hiding this comment

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

Please use TimeUnit so that it is self documenting.

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/TimeUnit.html

TimeUnit.SECONDS.toMillis(30L)

int resultCode = cf.get(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS);
out.println("Sync returned " + resultCode);
} catch (TimeoutException ex) {
out.println("Sync is timeout within " + CONNECTION_TIMEOUT + " ms");
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we throw an error?
The command may not have succeeded

Copy link
Member Author

Choose a reason for hiding this comment

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

@eolivelli pardon me.I may not get your idea clearly.
Do you mean that throwing this TimeoutException?

Copy link
Contributor

Choose a reason for hiding this comment

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

@maoling yes

Copy link
Contributor

Choose a reason for hiding this comment

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

Does this code need it's own 'try' block? Can this catch be moved to the outer 'try' statement?

} catch (IllegalArgumentException ex) {
throw new MalformedPathException(ex.getMessage());
} catch (InterruptedException | ExecutionException ex) {
Copy link
Contributor

Choose a reason for hiding this comment

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

About catching InterruptedException: http://www.javapractices.com/topic/TopicAction.do?Id=251
We don't do anywhere else in our code which maybe not a good practice.
What do you think @belugabehr ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I thought about it.
In this specific case we don't care. The CLI will exit.

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Got it. Makes sense.

Copy link
Contributor

Choose a reason for hiding this comment

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

When you catch the Interrupted exception, it clears the Thread's state. I would separate the catch into two blocks and be sure to reinstate the flag to 'interrupted' so that any other code will also quickly exit.

} catch (InterruptedException ie) {
    Thread.currentThread().interrupt();
   throw new CliWrapperException(ie);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes but in this case it is not really needed.
We can add it but not so important

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's always best to do it the "right" way... it will insulate the code from changes later when it may become needed.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's missing from everywhere else in the code unfortunately.
There's no harm adding it here anyway.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yep, better to add.
Better to file a JIRA for fixing it every where

@maoling
Copy link
Member Author

maoling commented Apr 4, 2019

image

@maoling
Copy link
Member Author

maoling commented May 23, 2019

ping @anmolnar @eolivelli
Could you plz take another look?

Copy link
Contributor

@eolivelli eolivelli left a comment

Choose a reason for hiding this comment

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

Looks good

@anmolnar
Copy link
Contributor

retest maven build

@asfgit asfgit closed this in e2bb6e8 May 23, 2019
asfgit pushed a commit that referenced this pull request May 23, 2019
- Thanks the original work from [arshad.mohammad ](https://issues.apache.org/jira/secure/ViewProfile.jspa?name=arshad.mohammad)
- more details in [ZOOKEEPER-2694](https://issues.apache.org/jira/browse/ZOOKEEPER-2694)

Author: maoling <maoling199210191@sina.com>

Reviewers: eolivelli@apache.org, andor@apache.org

Closes #823 from maoling/ZOOKEEPER-2694 and squashes the following commits:

41723cd [maoling] print the resultCode when sync has failed
95123c0 [maoling] make the Sync more user-friendly
a3ce170 [maoling] SYNC_TIMEOUT & use the TimeUnit.SECONDS.toMillis & a responsible way of handling the InterruptedException
df0bf73 [maoling] CliWrapperException
52c3ad0 [maoling] change CountDownLatch to CompletableFuture
0cc1edd [maoling] add the wait_timeout: 30s
cf01294 [maoling] ZOOKEEPER-2694:sync CLI command does not wait for result from server

(cherry picked from commit e2bb6e8)
Signed-off-by: Andor Molnar <andor@apache.org>
@anmolnar
Copy link
Contributor

Patch committed to 3.5 and master branches. Thanks @maoling !

RokLenarcic pushed a commit to RokLenarcic/zookeeper that referenced this pull request Sep 3, 2022
- Thanks the original work from [arshad.mohammad ](https://issues.apache.org/jira/secure/ViewProfile.jspa?name=arshad.mohammad)
- more details in [ZOOKEEPER-2694](https://issues.apache.org/jira/browse/ZOOKEEPER-2694)

Author: maoling <maoling199210191@sina.com>

Reviewers: eolivelli@apache.org, andor@apache.org

Closes apache#823 from maoling/ZOOKEEPER-2694 and squashes the following commits:

41723cd [maoling] print the resultCode when sync has failed
95123c0 [maoling] make the Sync more user-friendly
a3ce170 [maoling] SYNC_TIMEOUT & use the TimeUnit.SECONDS.toMillis & a responsible way of handling the InterruptedException
df0bf73 [maoling] CliWrapperException
52c3ad0 [maoling] change CountDownLatch to CompletableFuture
0cc1edd [maoling] add the wait_timeout: 30s
cf01294 [maoling] ZOOKEEPER-2694:sync CLI command does not wait for result from server
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