-
Notifications
You must be signed in to change notification settings - Fork 176
APEXCORE-626 shutdown-app in cli supports app-name as argument #564
APEXCORE-626 shutdown-app in cli supports app-name as argument #564
Conversation
Are there any unit tests for shutdown? |
I looked into |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please address the provided comment. The reset looks good.
{ | ||
ApplicationReport app = null; | ||
|
||
if (getApplication(appNameOrId) != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
app = getApplication(appNameOrId)
if (app == null) {
app = getApplicationByName(appNameOrId)
}
To avoid calling getApplication and getApplicationByName twice.
@@ -2178,6 +2178,19 @@ public void execute(String[] args, ConsoleReader reader) throws Exception | |||
|
|||
} | |||
|
|||
private ApplicationReport findApplicationReportFromAppNameOrId(String appNameOrId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function could be used in KillAppCommand#execute too
@@ -738,7 +738,7 @@ void printUsage(String cmd) | |||
"Kill a container")); | |||
connectedCommands.put("shutdown-app", new CommandSpec(new ShutdownAppCommand(), | |||
null, | |||
new Arg[]{new VarArg("app-id")}, | |||
new Arg[]{new VarArg("app-id/app-name")}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar change is needed at
globalCommands.put("shutdown-app", new CommandSpec(new ShutdownAppCommand(),
new Arg[]{new Arg("app-id")},
new Arg[]{new VarArg("app-id")},
line number 634
Looks good, can you squash all the commits and add JIRA id in the final commit message as per contributing guidelines (http://apex.apache.org/contributing.html). I will merge it after that |
3175b88
to
bc30b09
Compare
Jenkins, test me again! |
I added the following comment to the JIRA and it will be nice to address it in this PR: "Can we extend this to all the commands that accept the app-id? I see the following: connect app-id |
if (app == null) { | ||
app = getApplicationByName(appNameOrId); | ||
} | ||
return app; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the callers throw the identical exception when the returned app is null. Can we just throw that exception here and the caller can always assume app is non-null?
Thinking further, the current behavior - even with my proposed suggestion - fails the whole command if a single app-id/app-name is not found. Do we want to keep that behavior or modify it to only ignore the invalid app-id/app-name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The behavior seems to be inconsistent between different CL tools. I just checked docker start valid_container_name invalid_container_name
: this would start valid_container but not invalid_container. Then again when using apt-get install valid_package_name invalid_package_name
it just fails completely, installing neither of those packages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making findApplicationReportFromAppNameOrId()
throw a CLIException could
- on one hand clean up the code so we don't need to rewrite it every time
- on the other hand it would make it inconsistent with getApplication and getApplicationByName, where no exception is thrown.
Also if we leave the exception out of the method, we would still have the possibility of implementing the logic for "fail all vs. fail only for invalid appName" in the respective commands, which we do not have if we move it into the method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, it should be the best effort attempt. If application id or name is not found, the error needs to be reported, but it is necessary to continue to the next id/name. At the end, command should report all applications that were shutdown.
throw new CliException("Streaming application with id " + args[i] + " is not found."); | ||
ApplicationReport ap = findApplicationReportFromAppNameOrId(args[i]); | ||
if (ap == null) { | ||
throw new CliException("Streaming application with id or name " + args[i] + " is not found."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pls see my comment above about failing the command for the whole list when a single app is not found.
new Arg[]{new Arg("app-id")}, | ||
new Arg[]{new VarArg("app-id")}, | ||
new Arg[]{new Arg("app-id/app-name")}, | ||
new Arg[]{new VarArg("app-id/app-name")}, | ||
"Shutdown an app")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
=> "Shutdown app or apps"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggested extending this to other commands. Let me know what you think
Thanks for the reviews! EDIT: Actually it is tricky to add support for e.g Regarding the question whether a command should fail completely or not if one of the apps is not found, I would go with not running the command at all, the reason being that it feels nicer to me in terms of usability, when one mistypes an app name or app id and wants to make a correction to it afterwards. (Instead of having to retype the whole command only for the failed app-names or app-ids). I'd be happy to get some more input on that though! |
bc30b09
to
f092ad9
Compare
Okay, good point about multiple app-ids for the same name. Then it is not worth extending only for connect.... |
@sanjaypujare @florianschmidt1994 Whether other commands can support application name in addition to application id should be considered separatly for each command. I'd prefer not to block this PR and have separate JIRAs and PRs for each command that can take application name as an argument in addition to application id. |
I agree with @vrozov to have separate Jiras for supporting app-name in other commands. |
Are there any open issues left to do then? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sanjaypujare can you merge this if you don't have any additional comments.
"Shutdown an app")); | ||
new Arg[]{new Arg("app-id/app-name")}, | ||
new Arg[]{new VarArg("app-id/app-name")}, | ||
"Shutdown app or apps")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shutdown application(s) by id or name?
if (app == null) { | ||
app = getApplicationByName(appNameOrId); | ||
} | ||
return app; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, it should be the best effort attempt. If application id or name is not found, the error needs to be reported, but it is necessary to continue to the next id/name. At the end, command should report all applications that were shutdown.
@vrozov I have both the best effort and the existing approach at hand. How / Who will it be decided with option we will go with? Do we need more input from others for that? |
@florianschmidt1994 The best approach is to bring the discussion to dev@apex. Once dev community comes to an agreement, summarize the discussion in JIRA. |
af20bee
to
f5677d3
Compare
Thanks for all your input! As discussed on the mailing list we will go with the "best effort" approach. The "latest" commit (thanks rebase :D ) contains the discussed functionality as well as an additional test to ensure proper behavior. |
b2473fd
to
480d8b8
Compare
Run tests again |
if (apps[i - 1] == null) { | ||
throw new CliException("Streaming application with id " + args[i] + " is not found."); | ||
} | ||
String[] appNamesOrIds = Arrays.copyOfRange(args, 1, args.length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to check for duplicates?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd vote for going with the way it currently behaves, which is shutting down an app if it is found, and if it is specified as argument twice: printing an error message on the second time, because the app is already shut down.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
if (app == null) { | ||
throw new CliException("Streaming application with id or name " + args[i] + " is not found."); | ||
} | ||
throw new CliException("Streaming application with id or name " + args[i] + " is not found."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we throw exception and stop processing the kill command as opposed to what we decided to do for the shutdown command e.g. continue processing the remaining arguments? In that case we can also achieve some code reuse between shutdown and kill commands - building the app report list etc can be common code.
} | ||
|
||
yarnClient.killApplication(app.getApplicationId()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above - if an exception is thrown the processing stops.
// When processing the shutdown command for two valid and one invalid appNames | ||
String shutdownAppsCommand = "shutdown-app app1 notExisting app2"; | ||
cliUnderTest.processLine(shutdownAppsCommand, new ConsoleReader(), true); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be a good idea to flush the current System.out and System.err (or close them) to ensure you get complete/consistent output in your stdOut and stdErr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New squashed version uses autoflush on PrintStream now
"org.apache.log4j.*" | ||
}) | ||
@PrepareForTest({YarnClient.class, ApexCli.class, StramAgent.class}) | ||
public class ApexCliShutdownCommandTest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about adding a test for the kill command as well? You can add it here and rename the class .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment below on how to go from here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pls check the comments
480d8b8
to
8ccd1f0
Compare
The current version now implements the best effort approach as discussed on the mailing list. Unfortunately this is now inconsistent to how the kill-app command behaves, being that kill-app stops when an error occurs during killing of an application. I think there are two ways to go from here now:
|
@florianschmidt1994 after thinking about this a bit, we should address the kill command inconsistency in a separate JIRA and merge this PR as soon as comments are addressed. Will finish my review.... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
8ccd1f0
to
454e149
Compare
Added a minor change to fix a bug where the cli would wrongfully disconnect from currentApp |
} finally { | ||
if (currentApp != null) { | ||
if (app.getApplicationId().equals(currentApp.getApplicationId())) { | ||
currentApp = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In doing this you are assuming that shutdown succeeded or will succeed. If shutdown doesn't succeed why set currentApp to null?
Hey guys,
I am @pramod on github but not the Pramod in your team. :-) Could you
please remove me from this thread?
Thanks,
Pramod
…On Wed, Aug 9, 2017 at 3:25 PM, sanjaypujare ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In engine/src/main/java/com/datatorrent/stram/cli/ApexCli.java
<#564 (comment)>:
> + System.err.printf(errMessage, appNameOrId, appNameOrId);
+ return;
+ }
+
+ try {
+ JSONObject response = sendShutdownRequest(app);
+ if (consolePresent) {
+ System.out.printf("Shutdown of app %s requested: %s%n", app.getApplicationId().toString(), response);
+ }
+ } catch (Exception e) {
+ String errMessage = "Failed to request shutdown for app %s: %s%n";
+ System.err.printf(errMessage, app.getApplicationId().toString(), e.getMessage());
+ } finally {
+ if (currentApp != null) {
+ if (app.getApplicationId().equals(currentApp.getApplicationId())) {
+ currentApp = null;
In doing this you are assuming that shutdown succeeded or will succeed. If
shutdown doesn't succeed why set currentApp to null?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#564 (review)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABbl0GthHoaVytXj-UWC8DMAqO9dMUZks5sWjHpgaJpZM4Oh1kS>
.
|
My apologies, sorry about that! Unfortunately I think we can't do that, but you should be able to unsubscribe at the top right of the page, in the section notification. Also your email show have a link called "mute this thread", which should do the same. |
@florianschmidt1994 Please rebase |
The command shutdown-app now supports not only the app-id but also the app name as an argument. In case of multiple appIds or appNames the shutdown-app command follows a "best effort" approach, meaning that it tries to shutdown each app individually and prints an error message if the shutdown of an app fails, but continues to shutdown all the others. This commit adds the described functionality, documentation to the cli help messages and a test to ensure correct best effort behaviour.
454e149
to
9ea2cfb
Compare
|
The command shutdown-app now supports not only the app-id but also the
app name as an argument.
This commit adds both the functionality as well as the documentation to
the cli help messages