-
Notifications
You must be signed in to change notification settings - Fork 79
Polished yet basic ProcessIsolated #40
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
Polished yet basic ProcessIsolated #40
Conversation
|
Very weird dependency failure... resolves and runs locally 🤔 |
|
Ah ofc, missed a rebase |
|
Heh ok, failure was that SwiftPrometheus changed API... gotta love non-reproducible builds ¯_(ツ)_/¯ Comitting Package.resolved is a good thing iMHO :P |
|
Some nasty issues with supervision re the escalate change I'll get to the bottom but likely tomorrow. |
|
This includes a cherry picked #51 which should be merged first. |
|
Failure was #13 -- time to focus on it and fix then 👍 I'll do so tomorrow, unless someone wants to pick up :) |
|
Would welcome a review, best viewed in its entirety after reading the docs commit which is: f68f85b This also introduces .escalate which was needed to tie together supervision trees with this entire idea of process isolation |
| self.notifyParentWeDied() | ||
| self.notifyWatchersWeDied() | ||
| self.notifyParentOfTermination() | ||
| self.notifyWatchersOfTermination() |
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 "we" was reading a bit weird
|
All tests are integration tests, they are runnable by: |
| // finally, once prepared, you have to invoke the following: | ||
| // which will BLOCK on the master process and use the main thread to | ||
| // process any incoming process commands (e.g. spawn another servant) | ||
| isolated.blockAndSuperviseServants() |
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.
hoping to get rid of this part eventually, but for now good enough 🤔
yim-lee
left a comment
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.
Just feedback on the documentation changes
drexin
left a comment
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.
Just a few things. Overall looks very good.
| if let cluster = self._cluster { | ||
| self._clusterEventStream = try! EventStream(self, name: "clusterEvents") | ||
| let clusterEvents = try! EventStream<ClusterEvent>(self, name: "clusterEvents") | ||
| self._clusterEvents = clusterEvents // TODO: why stored on self 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.
Because it is required to create the ClusterControl which is created in a computed property in ActorSystem+Cluster
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.
Hm, I guess this can be done either way, we create control here or the stream 🤔
Let's leave it be for now though feels like we should create control 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.
| // end::imports[] | ||
|
|
||
| private struct BatSignal { | ||
| func becomeBatman() -> Batman { |
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.
Not sure this is a good idea, because copyright etc. Maybe use a different example.
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.
Huh, okey
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.
Fixed :) abb9a44
Remove all Fault handling code
== Motivation .escalate makes failures be escalated to parent upon failure, these are escalated more if the parent also does .escalate automatically. If one wants to isolate the failure, i.e. "stop it from bubbling up", keeping the supervision as .stop does the trick -- the actor which is .stop supervising stops, rather than escalates the issue. Watching is inherently "same-ish" to this -- watching is a superset of supervision escalate. A parent always is notified about child termination. Only watching a child though makes the death pact active. Alternatively, one may want to supervise the spawned child with .escalate, meaning that any failures the child does we shoudl get... but we will NOT get its .stop signals (!) which watching WOULD give us.
Minor bash fixups rebase fixups
|
I think we can merge. |
* implement top level watch and ensure we can escalate * =sup #31 Implements .escalate supervision scheme == Motivation .escalate makes failures be escalated to parent upon failure, these are escalated more if the parent also does .escalate automatically. If one wants to isolate the failure, i.e. "stop it from bubbling up", keeping the supervision as .stop does the trick -- the actor which is .stop supervising stops, rather than escalates the issue. Watching is inherently "same-ish" to this -- watching is a superset of supervision escalate. A parent always is notified about child termination. Only watching a child though makes the death pact active. Alternatively, one may want to supervise the spawned child with .escalate, meaning that any failures the child does we shoudl get... but we will NOT get its .stop signals (!) which watching WOULD give us. * Allow process.exit() when failure reaches guardian * only escalation should cause escalated to be populated in signal * -act,fault #50 remove fault handling code and test Remove all Fault handling code * -act,fault #50 remove fault handling code and test * Hardening process isolated, node watcher uses event to detect down * Implemented that master process restarts only as many times as configured * Ensuring that backoff restarts work in process supervision Minor bash fixups rebase fixups * Documentation for ProcessIsolated * can't yet validate docs on linux * compilation fix, no getpid on examples * one off error in test * Address comments and reword deathwatch docs * remove batman pun
Motivation:
ProcessIsolated is likely going to be our main answer for isolation until we get better answers, as such, it has to be really polished.
In this PR I aim to explain how to use it as well as provide tests for the escalating failures to the guardians, which in turn kill the process, which causes the servant supervision to kick in and thus show off real life supervision scenarios with process isolation.
This can be adopted immediately in real systems to provide isolation, even with Swift not having any cool isolation features right now.
Modifications:
Result:
Production ready
ProcessIsolated.