-
-
Notifications
You must be signed in to change notification settings - Fork 483
WFCORE-7623: signal if input is idle #6860
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,6 +36,7 @@ public CliProcessWrapper(boolean modular){ | |
| private Process cliProcess; | ||
| private volatile StringBuffer cliOutputBuffer = new StringBuffer(); | ||
| private BufferedWriter bufferedWriter = null; | ||
| private boolean idleInput = false; | ||
|
|
||
| /** | ||
| * Clear current output buffer | ||
|
|
@@ -178,7 +179,7 @@ public void destroyProcess() { | |
| */ | ||
| public String getCurrentPrompt(){ | ||
| if(cliOutputBuffer.toString().contains("\n")) { | ||
| return cliOutputBuffer.toString().substring(cliOutputBuffer.toString().lastIndexOf("\n")+1); | ||
| return cliOutputBuffer.substring(cliOutputBuffer.toString().lastIndexOf("\n")+1); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please always apply the standard code formatting, otherwise in the future applying the format will generate changes
Comment on lines
181
to
+182
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What hapends if after reading"cliOutputBuffer.toString().contains("\n")" the cliOutputBuffer changes in between before executing the return?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The method is called after we made sure the buffer shouldn't be changing. But even if it changed it should still be returning the last line of the output, worse case |
||
| }else{ | ||
| return cliOutputBuffer.toString(); | ||
| } | ||
|
|
@@ -279,18 +280,15 @@ private boolean outputHasPrompt(String prompt){ | |
| if (buffer.startsWith("Exception")){ | ||
| throw new RuntimeException(buffer); | ||
| } | ||
| if(buffer.contains("\n")) { | ||
| if (prompt == null) { | ||
| return buffer.substring(buffer.lastIndexOf("\n")+1).matches(".*[\\[].*[\\]].*"); | ||
| } else { | ||
| return buffer.substring(buffer.lastIndexOf("\n")).contains(prompt); | ||
| } | ||
| }else{ | ||
| if (prompt == null) { | ||
| return buffer.matches(".*[\\[].*[\\]].*"); | ||
| } else { | ||
| return buffer.contains(prompt); | ||
| } | ||
| if (!idleInput) { | ||
| return false; | ||
| } | ||
|
|
||
| String currentPrompt = getCurrentPrompt(); | ||
| if (prompt == null) { | ||
| return currentPrompt.matches(".*[\\[].*[\\]].*"); | ||
| } else { | ||
| return currentPrompt.contains(prompt); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -302,6 +300,8 @@ public CliResultsReader(InputStream inputStream){ | |
| cliStream = inputStream; | ||
| } | ||
|
|
||
| int idleCounter = 0; | ||
|
|
||
| @Override | ||
| public void run() { | ||
| try(java.io.BufferedReader br = new java.io.BufferedReader(new java.io.InputStreamReader(cliStream, StandardCharsets.UTF_8))){ | ||
|
|
@@ -310,6 +310,19 @@ public void run() { | |
| // While the next character is a valid character and isn't null | ||
| while ((intCharacter = br.read()) != -1 && (character = (char)intCharacter) != null) { | ||
| cliOutputBuffer.append(character); | ||
| if (character == '\n') { | ||
| idleInput = false; | ||
| idleCounter = 0; | ||
| } | ||
|
|
||
| // reader is not ready either after processing CLI output = idle prompt (this happens at most once per line) | ||
| // or intermittently while processing user input - this has to be ignored | ||
| if (!br.ready()) { | ||
| idleInput = idleCounter <= 1; | ||
| idleCounter++; | ||
| } else { | ||
| idleInput = false; | ||
| } | ||
|
Comment on lines
+320
to
+325
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not get the behaviour of this logic. Could you explain it here? , why "idleCounter <= 1" and why you do it if the buffer is not ready?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand the process will echo the user input, and here what you want to do is to signal when this echo has not finished yet. Also, I understand that the server output is processed as an stream, and I guess this is the main issue. Correct me if I am wrong, each echo will be following by a new line, and in that moment the output of the command result will start, probably it will contain several lines. I do not get how this will help with this: which seems to be the main issue since Would not be easier to use a producer consumer pattern on the threads that reads the std out / err and produce line by line?, consumers will wait until a line is ready, consumers will not read lines in the middle of processing. In general, looks like that sharing the cliOutputBuffer between the CliResultsReader threads and the main thread is quite problematic
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As it is the If we were reading the output line by line we couldn't check the current prompt since that's not a complete line yet. And it would still need some mechanism to tell us the producer is finished producing, wouldn't it? if If we start with e.g.
We now execute a command, |
||
| } | ||
| } catch (IOException e) { | ||
| fail("Failed to read process output or error streams: " + e.getLocalizedMessage()); | ||
|
|
||
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 variable must be volatile, otherwise there will not be visibility guarantees between the three threads that modify/read it