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

[STORM-3385] Avoid two threads reading from the same input stream of a process #3005

Merged
merged 1 commit into from
May 17, 2019

Conversation

Ethanlm
Copy link
Contributor

@Ethanlm Ethanlm commented May 1, 2019

https://issues.apache.org/jira/browse/STORM-3385

This is not causing any problem so far. But having two threads are reading from the same input stream doesn't seem right.

@srdo
Copy link
Contributor

srdo commented May 1, 2019

@Ethanlm
Copy link
Contributor Author

Ethanlm commented May 1, 2019

@srdo Yes it's the purpose of making it to null. So that separate thread can be skipped. Then there will be only one thread reading from process.getInputStream()

We also want exitCallback to be null since Line 74 is process.waitFor. It doesn't make sense to have two threads doing the same thing, which seems problematic

@srdo
Copy link
Contributor

srdo commented May 1, 2019

No, I mean exitCodeCallback is already null in the line you're changing https://github.com/apache/storm/blob/master/storm-client/src/jvm/org/apache/storm/daemon/supervisor/ClientSupervisorUtils.java#L67. Since it is already null, we can't hit the case where Utils.asyncLoop is called.

@Ethanlm
Copy link
Contributor Author

Ethanlm commented May 2, 2019

No. if (logPrefix != null || exitCodeCallback != null) { is a "OR" condition. Utils.asyncLoop will not be called only when logPrefix and exitCodeCallback are both null.

@srdo
Copy link
Contributor

srdo commented May 3, 2019

Sorry, I obviously wasn't paying enough attention when looking at this. +1

@Ethanlm
Copy link
Contributor Author

Ethanlm commented May 3, 2019

No worries. Thanks for review.

@@ -64,7 +64,7 @@ public static int processLauncherAndWait(Map<String, Object> conf, String user,
final Map<String, String> environment, final String logPreFix)
throws IOException {
int ret = 0;
Process process = processLauncher(conf, user, null, args, environment, logPreFix, null, null);
Process process = processLauncher(conf, user, null, args, environment, null, null, null);
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree this is a good change.

It isn't obvious to me that adding a prefix should cause the threading behavior. I'd rather see an explicit API with either a name change or a thread parameter rather than relying on logPrefix.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes I totally agree. Filed a separate jira: https://issues.apache.org/jira/browse/STORM-3389

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks

@@ -64,7 +64,7 @@ public static int processLauncherAndWait(Map<String, Object> conf, String user,
final Map<String, String> environment, final String logPreFix)
throws IOException {
int ret = 0;
Process process = processLauncher(conf, user, null, args, environment, logPreFix, null, null);
Process process = processLauncher(conf, user, null, args, environment, null, null, null);
if (StringUtils.isNotBlank(logPreFix)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not remove this here instead for consistency? I just searched all the callers and all except here rely on processLauncher and don't call Utils.readAndLogStream.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the difference is that processLauncherAndWait wait for the process to finish, which is synchronous. processLauncher doesn't wait, which is asynchronous.

Copy link
Contributor

Choose a reason for hiding this comment

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

I meant do we really need to handle Utils.readAndLogStream here instead of deferring in processLauncher? If not we can just remove the if statement instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do we want to create a new thread just for readAndLogStream? I think it makes sense to keep Utils.readAndLogStream here. Btw this is the only caller of processLauncher that set processExitCallback parameter to null.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK I got it. You're right. What we should do it is STORM-3389 instead, the change here looks reasonable.

Copy link
Contributor

@HeartSaVioR HeartSaVioR left a comment

Choose a reason for hiding this comment

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

+1, assuming we will deal with STORM-3389 sooner.

@asfgit asfgit merged commit eacd235 into apache:master May 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants