I'm not seeing how IOC is sufficient to bring up a web container for example. There still needs to be a start notion that allows the service
to configure all of its internals it seems. How would start on the service interceptor be able to do this?
I actually feel lifecycle is unnecessary if read-ahead and IOC was implemented. It would be replaced by ordered configuration and valves. The user would have two options start/stop the valve or deploy/undeploy the service.
One solution would be to run core services/deployers in "ring zero"
a sort of controlling sub-machine/extensible kernel. This would make other services slightly second class citizens.
This still does not solve the problem generally, e.g.
1) how to allow pluggable logging (currently implemented with a boot.log and server.log)
2) how to run the boot under a security context and still have pluggable security
3) what if you want your mbean persistence from the db for your core services when the db connection isn't deployed until later
It's almost like you a need a separate bootstrap "process"
that boots enough to configure the main machine before being discarded in favour of it? A bit like the bios/boot block in the pc.
Yes, there would still need to be lifecycle for components that don't support IOC.
I don't see start() as a configuration issue.
Start is a valve operation on an already confgured service, typically performing
things like jndi or server port binding.
e.g. for a webapp it would link an already configured webcontext to the web container.
What are examples where configuration can only be done at activation?
void setJNDIName(String jndiName)
this.jndiName = jndiName;
can be replaced with:
void setJNDIBinding(JNDIBinding binding)
leaving the container to handle the real binding
Bill Burke wrote:
I was also hoping that you could supply a mixin class that handled service lifecycle so that POJO's could be involved with lifecycle and not have to implement any interface. Hmmmm, I guess you could do this with AOP introduction. Bill
Not sure what you mean here adrian. Some services require a 2 stage startup. Clustering is an example. At create time, all services register with the ClusterPartition for events. Then in start(), ClusterPartition actuall joins the group. This is so that all state synchronization services can register for the initial state synch before the cluster partition joins the group.
Right, I agree, start is not a configuration issue, and we don't use it as such now. It is a lifecycle op to notify the component to use the current configuration to bring the component into the start state. In a pojo framework with only aspects/interceptors introducing the service level functionality start can be handled outside of the component.
For integrating containers like the web container which already have a lifecycle notion its easier to simply delegate the start op to the component to bring up its connectors, etc. Its not that the web container does not support IOC, its already does by virtue of the mbean attributes. Taking all of the configuration info to a running web container is no something I can see being done by an IOC framework though.
I'm arguing that the two stages are really two different ideas.
The first phase is configuration/deployment where the stateful services are
configured to be part of the cluster partition.
This is what needs to be ordered so we can build up the services
into a ready service in the correct order and provide information to the valves
about needs to happen during phase 2.
Phase 2 is where we release the valve (in this case let the partition
join the grousp).
I see what you mean by the callbacks, they are a form of lifecycle
but these aren't really configuration.
Phase 2's start/stop valve operations can be invoked from deployment
or manually from some the console.
You could configure some services to be "deployed" but not active,
i.e. phase 2 does not happen at startup, it is either a manual process
(or even lazily done when the service is actually used).