-
-
Notifications
You must be signed in to change notification settings - Fork 235
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
Ensuring completion-listener.ts listen to a single close event emitte… #464
Conversation
…d from each command.
Rethinking on this, this change includes also an edge case that doesn't work:
---> It will resolve altho the first command is also alive So I might be going on the wrong direction here would love to here your tought on the initial design of the |
Another option would be a design-level change such as: Adding a new
And a modification for Would love to hear your mind on it 👍 |
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.
Restarting is tricky; because each option you set changes the closing conditions of a command, the flow controllers wrap the close observable so that all looks simple on the completion listener side.
Adding a new restart API
I think this could be done for convenience, but not as a way of fixing this issue.
this change includes also an edge case that doesn't work:
This is true, but this PR is at least an improvement over not doing anything.
The optimal solution is probably to retain the last emitted close event of each command until they all exit.
So how would u recommend proceeding? Do you wish to have this fix for now? (as you said just a slight improvement for the current state) |
src/completion-listener.ts
Outdated
@@ -86,7 +86,8 @@ export class CompletionListener { | |||
* @returns A Promise that resolves if the success condition is met, or rejects otherwise. | |||
*/ | |||
listen(commands: Command[]): Promise<CloseEvent[]> { | |||
const closeStreams = commands.map((command) => command.close); | |||
const closeStreams = commands.map((command) => command.close.pipe(take(1))); | |||
|
|||
return Rx.lastValueFrom( | |||
Rx.merge(...closeStreams).pipe( | |||
bufferCount(closeStreams.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.
So how would u recommend proceeding?
I think that replacing these lines with Rx.combineLatest()
+ removing the take(1)
above can achieve retaining the last emitted close event.
We can then also fix your edge case from #464 (comment) with a filter()
operator that checks if every command is indeed closed.
This means waiting until every command emits another close event.
WDYT?
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.
Yea that sounds legit, at-least the first part, seems like combineLatest
can do the job 👍 Ill try to change the implementation accordingly
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.
@gustavohenke I've pushed the changes, the only drawback using the combineLatest
is that it actually keep the close events according to the registered stream and not by the actual order they were emitted, So beside accepting your offer I also added a map
to sort it via the startingDate
of the event, would love to hear if you got any better suggestion here 👍
-Adding `ipc` option by default. -Adjusting specs.
src/completion-listener.ts
Outdated
Rx.merge(...closeStreams).pipe( | ||
bufferCount(closeStreams.length), | ||
Rx.combineLatest(closeStreams).pipe( | ||
filter((exitInfos) => exitInfos.every((exitInfo) => exitInfo.exitCode !== 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.
exitCode
is never null here. You need to look at the event's command for the current state
filter((exitInfos) => exitInfos.every((exitInfo) => exitInfo.exitCode !== null)), | |
filter((exitInfos) => exitInfos.every(({ command }) => command.state !== 'started')), |
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.
Yea good point 👍 This means to access it we would need to either add it to the CommandInfo
which I assume we don't want as it's a public interface or send it explicitly right?
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.
Heya, I've fixed this myself and added an extra test too.
You were right, adding to CommandInfo
is not a good idea, but so wasn't right to pass the state in the close event since that's pretty static. Can check commands
variable just outside the loop, though.
This comment was marked as off-topic.
This comment was marked as off-topic.
Hey! This is now available in v9.0.0. |
Currently, the
CompletionListener
sets abufferCount
upon commands close streams to conclude once commands are finished and then evaluates the exit code and determines thesuccess/fail
conditions.Continued to the issue brought here, calling manually
Command
-kill/start
API's manually, causes a bug where theCompletionListener
resolves before all commands had exited ( as a single command can emit multiple close events ).This PR changes the behaviour to take a single emit event from each command in order to conclude termination.
Disclaimer:
Potentially I would love to find a way to take the last exit command emitted from each
Command
tho I couldn't find a way would appreciate any suggestion 👍 mine while I kept things the same.Side effects
completion-listener.spec.ts
file to all use the same command exit helperAllowipc
for spawned commandsResolves: #463