GitHub user aledsage opened a pull request:
https://github.com/apache/brooklyn-server/pull/761
Async entities
Adds `AsyncApplication`: An app that starts up asynchronously. Calling
start will call start on its children, but it does not expect the children to
have started by the time the start() effector has returned. Instead, it infers
from the children's state whether they are up or not.
An example use-case is where the app kicks off some async children. These
children call out to whichever system they integrate with (e.g. provisioning
resources), and then several hours later get callbacks to say whether it
started/succeeded. Instead of leaving the `start()` method running for several
hours, we let the start method return and then we transition automatically to
the right state. I didn't want to leave the `start()` method executing for a
long time, because then on Brooklyn-restart the effector would have been
interrupted and it would not handled it well!
---
The computation of service-up and service-state (i.e. the enrichers) is
very different for the async app. As the javadoc says:
```
Calculates the "service.state" and "service.isUp", based on the state of
the children. It
also transitions from expected=starting to expected=running once all of the
children have
finished their starting.
This does <em>not</em> just rely on the "service.problems" and
"service.notUp.indicators"
because those make different assumptions about the expected state. Instead
it seems much
easier to implement the specific logic for async startup here.
```
Before resorting to this approach, I tried to reuse/adapt the standard
enrichers that are in `AbstractApplication` and `ServiceStateLogic`. However, I
would either have made that complicated code much more complicated, or
reimplemented a huge chunk as an alternative enricher. The big difference is
that we want to automatically transition to `expected=running`.
Overall, it is therefore simpler to implement the specific enricher for
AsyncApplication.
I also did *not* use the same pattern for `service.notUp.indicators` and
`service.problems`. Instead of using these to infer whether we are up/healthy,
it sets `service.isUp` and `service.state` directly. It also sets the
indicators to explain why we are in the given state. This is a far simpler
pattern when we can compute our state directly, and where we don't expect users
to customize it with completely different ways of telling if we're up. In the
past, the race conditions and complexity of entities using separate enrichers
for indicators caused us a lot of pain in non-deterministic tests etc (which we
ironed out over a long period of time).
---
The other commit (`AsyncStartable marker interface`) is important for if we
restart Brooklyn or if we failover in HA. On rebind, a normal entity that is
"starting" will be set as "on-fire" because it's effector will not
automatically resume. That behaviour is not applicable for `AsyncStartable`.
You can merge this pull request into a Git repository by running:
$ git pull https://github.com/aledsage/brooklyn-server async-entities
Alternatively you can review and apply these changes as the patch at:
https://github.com/apache/brooklyn-server/pull/761.patch
To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:
This closes #761
----
commit b7247784dc3854bf873d41d41bb4a730e65dfc0d
Author: Aled Sage <[email protected]>
Date: 2017-07-04T06:07:05Z
Adds AsyncStartable marker interface
commit d3e8cac8dd1dbe86c5494dcf4bb0d7fd0bcc6e16
Author: Aled Sage <[email protected]>
Date: 2017-07-06T15:07:15Z
Adds AsyncApplication, and tests
----
---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---