Investigate the ability to support unresolved services. This implies the following:
- A dependency on an unresolved service is equivalent to a dependency on a DOWN service.
- When a service is removed, rather than recursively removing dependents (like today), instead the service is set to the unresolved state.
- An unresolved service has no Service Value object, and no dependencies.
- A dependency on a non-existent service causes an unresolved service to automatically be created for that dependency, rather than a resolve exception like today.
- Circularity is still forbidden; any service which would cause a cycle is rejected and cannot be installed.
- Resolution happens on each service as it is installed. Each installed service has to locate and wire up (or create) its dependencies; it also has to locate dependents, and detect circularity issues.
- This change largely obviates the need for batches, since services can be installed in any order, though the atomic nature of batch installs might still be desirable from an ease-of-use standpoint; however I'd be inclined to remove batches altogether.
- A service can effectively be replaced by removing the old one and installing a new one.
- ServiceController has to be split into two entities. One entity is a reference, by name, which contains the list of dependents. This is what gets registered in the registry, and what is used for user interactions; also, this is what dependencies are expressed in terms of. The other is the service controller instance, which contains the dependencies and state information, which is what Service implementations "see". When a service is removed, the old controller instance will "die". When a service is installed, a new controller instance is created and attached to the reference.
- Unresolved services which are not dependencies of any other service are automatically destroyed.
1. Are listeners attached to the reference, or the controller instance? In the former case, a listener will stay around forever until it is removed or until the service is unresolved and unreferenced. In the latter case, the listener lifecycle is tied to the resolved status of the service, so once a service becomes unresolved (i.e. "removed" by current terminology), the listener is removed.
2. It becomes possible to "add" optional dependencies at runtime using one of a couple possible approaches:
2.a. When an optional dependency becomes available, stop the dependent, inject the dependency, and restart the dependent (and, recursively, all its dependents).
2.b. When an optional dependency becomes available, put the dependent in a special "starting more" state which must be exited successfully for the dependency to be added. During this window the new dependency cannot be stopped (just as if a regular dependent were starting). If the additional service fails to be registered then the dependency is not added but the dependent state is unaffected.
2.c. When an optional dependency becomes available, simply call its injectors on dependents without any other notice. The dependent will need to monitor its injectors or provide a special implementation to perform a specific action.
2.d. Take no action; the optional dependencies available (if any) at the time the service is installed are the dependencies used for the life of the service, and newly appearing optional dependencies are ignored.
2.(addendum) In all cases, if an optional dependency is added to a service (at service definition time or any time after), the optional dependency becomes mandatory for the remaining life of the service (though it is also an open question whether to unregister any STOP_REQUESTED optional dependencies when a service is stopped, or whether this may only be done when a service is removed). Tracking removal of optional dependencies on running services defeats the purpose of having a dependency.
3. Error reporting is heavily affected. We need a way to "checkpoint" to identify dependencies on unresolved services, or report them in some other reasonable way, which is challenging given the concurrent nature of resolution and installation.