You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Christian Essl <ch...@yahoo.de> on 2003/09/21 09:44:07 UTC

[HiveMind] DeferredService performance

I think the Proxy created for a deferred Service is currently a bit slow, 
because each call to a Service method first checks synchronized if the 
service is there. While the Proxy is not anymore returned once the actual 
Service is loaded I think most users of the Service will still go through 
the proxy (You know: generally early Objects live longest and are most 
used).

I would suggest the proxy to implement the GoF state pattern (an idea I got 
from commons-collection FastArrayList):

You have two proxies where the outer one contains the inner one. The 
outerone just plainly gives further to a service field which is either the 
innter proxy or the actual loaded service. The inner proxy is like the 
current deferred proxy:

The code of a ready proxy would look like this: (This would of course have 
to be produced with JavaAssist):

public class OuterProxy implements ServiceInterface{

	private ServiceExtenstionPointImpl _sep;
	private InnerProxy _inner = new InnerProxy();
	private ServiceInterface _service = new InnerProxy();

	//an example method of the ServiceInterface
	public Object exampleMethod(Object arg){
		return _service.exampleMethod(arg);
	}

	//the innerproxy
	public class InnerProxy implements ServiceInterface{
		//method which loads the actual service
		private synchronized ServiceInterface getService(){
			if(_service != this)
				return _service;
			_service = _sep.constructServiceImplementation();
			return _service;			
		}

		//and the exampleMethod
		public Object exampleMethod(Object arg){
			return this.getService().exampleMethod(arg);
		}

	}
}

This also prevents the - potential - method conflict that can happen when a 
ServiceInterface implements  the SERVICE_ACCESSOR_METHOD_NAME (_service) 
method.

By the way I saw this when I was looking for a way to implement basic 
livecycle management. Have you thought of a destroy method. I think it is 
realy needed before Database, DAO, Pool, Cache, etc Services can be 
implemented.





RE: [HiveMind] DeferredService performance

Posted by "Howard M. Lewis Ship" <hl...@comcast.net>.
I did some refactoring and implemented the new deferred service model; seems to work just fine.
Don't have before and after performance numbers, but its pretty obvious that after the first
invocation, it has to be faster, since its a) avoiding a method call and b) avoiding a synchronized
block.  Good stuff, thanks for the idea.

--
Howard M. Lewis Ship
Creator, Tapestry: Java Web Components
http://jakarta.apache.org/tapestry
http://jakarta.apache.org/commons/sandbox/hivemind/
http://javatapestry.blogspot.com

> -----Original Message-----
> From: Christian Essl [mailto:christianessl@yahoo.de] 
> Sent: Sunday, September 21, 2003 6:39 PM
> To: Jakarta Commons Developers List
> Subject: Re: [HiveMind] DeferredService performance
> 
> 
> > Javassist doesn't do inner classes, so there's still going 
> to be some
> > kind of _setService() kind of
> > method used by the proxy when it replaces itself.
> 
> Thank you that's right, and as you see I don't realy know Javassist.
> 
> >
> > I'm using "_" to indicate "infrastructure" methods, in the believe 
> > that
> > this will not cause a
> > conflict. Between that, and method overloading (by 
> parameter type) I 
> > would not be too worried about
> > method name conflicts.  We should document that service 
> methods should 
> > not contain method names with
> > a leading underscore (perhaps enforce that as well).
> 
> I agree and would say if there is a conflict it is enforced 
> any way (maybe 
> a meaningfull exception).
> 
> ????? LifeCycle ???????
> 
> Just a few things I thought about:
> 
> > I see it as an added service model,
> > by leveraging ThreadEventNotifier and a ThreadLocal, much like the
> > "threaded" service model. Also,
> > there should be another lifecycle interface, like 
> Initializable, for 
> > service implementations ...
> > "Passivatable"? Ugh.
> 
> Yes an additional interface would be needed (It is hard for 
> me to find a 
> good name - English is not my first language).
> 
> Actually I thought initially of two other cases: First a 
> balance to the 
> startup phase where the Registry (and all the Services) are 
> terminated. In 
> this case the user has to take care that no thread uses anymore any 
> services and than he calles Registry.terminate(). All 
> ServiceModels should 
> and can be stopped in this case. I think that's currently the most 
> important case for ConnectionPools etc. The second case is about 
> termination of certain Services during the Runntime of the Registry.
> 
> > I'm concerned about degenerate cases; what if a service, when it
> > passivates, invokes methods on
> > other services, activating them? We might need a system of locks or 
> > checks to handle those cases.
> 
> I would say both (of my) cases will need a dependency-registry, which 
> controls the termination and checks for circularities. If a 
> service is 
> about to be stopped all the dependend services will be 
> stopped first.  
> While I think the definition of the dependencies 
> conceptionally belongs in 
> the initializeService method I would still keep it in the 
> hivemodule.xml 
> (It is just easier to implement, because Services neither 
> know their id nor 
> the id of the services they depend on or of their Factory).
> 
> Do you think this is a possible way? Is it enough?
> 
> 
> > Actually, much like EJBs, a service which can be pooled may be 
> > interested
> > in when it is brought out
> > of the pool and brought into active service for a thread, 
> and when it is 
> > passivated and stored back
> > into the pool. One interface ("ServiceLifecycle"?), two methods.
> >
> 
> Therefore (and because pooling is for my cases not the same 
> as destorying) 
> I would suggest a shutdown process like this:
> 
> 1) ServiceExtensionPointImpl.destroyService() -> 
> ServiceImplementationConstructor.destroyCoreService(Object 
> coreService)
> 
> 2a) CreateClassServiceConstructor() -> ((Destroyable) coreService) 
> .destroy()
> 
> 2b) InvokeFactoryServiceConstructor() -> 
> ServiceImplementationFactory.destroyCoreService(Object 
> coreService) -> 
> ((Destroyable) coreService).destroy();
> 
> ad 1) The ServiceExtensionPointImpl checks if the Service can 
> be destroyed 
> now (normally only if the registry is shut down). The SEPI 
> also remembers 
> the CoreServiceImpl. The Threaded takes it from the 
> threadlocal. If the 
> threaded wants to destroy (or pool) one of its CoreImpl it calls the 
> ServiceImplementationConstructor with the CoreService from 
> the threadlocal.
> 
> ad 2a) the CreateClassServiceConstructor just checks if the 
> CoreService 
> wants to be notified of destroy and notifies it.
> 
> ad 2b) the InvokeFactoryServiceConstructor gives the 
> coreService further to 
> the Factory which created it. The Factory can now do pooling etc (the 
> Pooling interface depends on the factory). The factory (if it 
> does not 
> pool) must than check if the coreService wants to be informed 
> that it is 
> destroyed (alternatively it could return a boolean indicating 
> wheter this 
> check should be done by the InvokeFactoryServiceConstructor).
> 
>     Regarding the second case (unloading a Single threaded 
> Service during 
> Registry runntime) I would say we need an extra ServiceModel. 
> It would be 
> quite similar to the deferred-model but it could also change 
> back to the 
> deferred state. It also keeps a count of threads acessing the current 
> Service. When asked to shutdown it first changes to the 
> deffered state. 
> Than waits until the last thread has left the (old) 
> CoreService and than 
> does the shutdown process as described above. If the service is newly 
> needed it starts it like the deffered proxy.
> 
> It would be nice if you could comment on that and I would 
> realy like to try 
> implement such a thing.
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> 


RE: [HiveMind] DeferredService performance

Posted by "Howard M. Lewis Ship" <hl...@comcast.net>.
I did some refactoring and implemented the new deferred service model; seems to work just fine.
Don't have before and after performance numbers, but its pretty obvious that after the first
invocation, it has to be faster, since its a) avoiding a method call and b) avoiding a synchronized
block.  Good stuff, thanks for the idea.

--
Howard M. Lewis Ship
Creator, Tapestry: Java Web Components
http://jakarta.apache.org/tapestry
http://jakarta.apache.org/commons/sandbox/hivemind/
http://javatapestry.blogspot.com

> -----Original Message-----
> From: Christian Essl [mailto:christianessl@yahoo.de] 
> Sent: Sunday, September 21, 2003 6:39 PM
> To: Jakarta Commons Developers List
> Subject: Re: [HiveMind] DeferredService performance
> 
> 
> > Javassist doesn't do inner classes, so there's still going 
> to be some
> > kind of _setService() kind of
> > method used by the proxy when it replaces itself.
> 
> Thank you that's right, and as you see I don't realy know Javassist.
> 
> >
> > I'm using "_" to indicate "infrastructure" methods, in the believe 
> > that
> > this will not cause a
> > conflict. Between that, and method overloading (by 
> parameter type) I 
> > would not be too worried about
> > method name conflicts.  We should document that service 
> methods should 
> > not contain method names with
> > a leading underscore (perhaps enforce that as well).
> 
> I agree and would say if there is a conflict it is enforced 
> any way (maybe 
> a meaningfull exception).
> 
> ????? LifeCycle ???????
> 
> Just a few things I thought about:
> 
> > I see it as an added service model,
> > by leveraging ThreadEventNotifier and a ThreadLocal, much like the
> > "threaded" service model. Also,
> > there should be another lifecycle interface, like 
> Initializable, for 
> > service implementations ...
> > "Passivatable"? Ugh.
> 
> Yes an additional interface would be needed (It is hard for 
> me to find a 
> good name - English is not my first language).
> 
> Actually I thought initially of two other cases: First a 
> balance to the 
> startup phase where the Registry (and all the Services) are 
> terminated. In 
> this case the user has to take care that no thread uses anymore any 
> services and than he calles Registry.terminate(). All 
> ServiceModels should 
> and can be stopped in this case. I think that's currently the most 
> important case for ConnectionPools etc. The second case is about 
> termination of certain Services during the Runntime of the Registry.
> 
> > I'm concerned about degenerate cases; what if a service, when it
> > passivates, invokes methods on
> > other services, activating them? We might need a system of locks or 
> > checks to handle those cases.
> 
> I would say both (of my) cases will need a dependency-registry, which 
> controls the termination and checks for circularities. If a 
> service is 
> about to be stopped all the dependend services will be 
> stopped first.  
> While I think the definition of the dependencies 
> conceptionally belongs in 
> the initializeService method I would still keep it in the 
> hivemodule.xml 
> (It is just easier to implement, because Services neither 
> know their id nor 
> the id of the services they depend on or of their Factory).
> 
> Do you think this is a possible way? Is it enough?
> 
> 
> > Actually, much like EJBs, a service which can be pooled may be 
> > interested
> > in when it is brought out
> > of the pool and brought into active service for a thread, 
> and when it is 
> > passivated and stored back
> > into the pool. One interface ("ServiceLifecycle"?), two methods.
> >
> 
> Therefore (and because pooling is for my cases not the same 
> as destorying) 
> I would suggest a shutdown process like this:
> 
> 1) ServiceExtensionPointImpl.destroyService() -> 
> ServiceImplementationConstructor.destroyCoreService(Object 
> coreService)
> 
> 2a) CreateClassServiceConstructor() -> ((Destroyable) coreService) 
> .destroy()
> 
> 2b) InvokeFactoryServiceConstructor() -> 
> ServiceImplementationFactory.destroyCoreService(Object 
> coreService) -> 
> ((Destroyable) coreService).destroy();
> 
> ad 1) The ServiceExtensionPointImpl checks if the Service can 
> be destroyed 
> now (normally only if the registry is shut down). The SEPI 
> also remembers 
> the CoreServiceImpl. The Threaded takes it from the 
> threadlocal. If the 
> threaded wants to destroy (or pool) one of its CoreImpl it calls the 
> ServiceImplementationConstructor with the CoreService from 
> the threadlocal.
> 
> ad 2a) the CreateClassServiceConstructor just checks if the 
> CoreService 
> wants to be notified of destroy and notifies it.
> 
> ad 2b) the InvokeFactoryServiceConstructor gives the 
> coreService further to 
> the Factory which created it. The Factory can now do pooling etc (the 
> Pooling interface depends on the factory). The factory (if it 
> does not 
> pool) must than check if the coreService wants to be informed 
> that it is 
> destroyed (alternatively it could return a boolean indicating 
> wheter this 
> check should be done by the InvokeFactoryServiceConstructor).
> 
>     Regarding the second case (unloading a Single threaded 
> Service during 
> Registry runntime) I would say we need an extra ServiceModel. 
> It would be 
> quite similar to the deferred-model but it could also change 
> back to the 
> deferred state. It also keeps a count of threads acessing the current 
> Service. When asked to shutdown it first changes to the 
> deffered state. 
> Than waits until the last thread has left the (old) 
> CoreService and than 
> does the shutdown process as described above. If the service is newly 
> needed it starts it like the deffered proxy.
> 
> It would be nice if you could comment on that and I would 
> realy like to try 
> implement such a thing.
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [HiveMind] DeferredService performance

Posted by Christian Essl <ch...@yahoo.de>.
> Javassist doesn't do inner classes, so there's still going to be some 
> kind of _setService() kind of
> method used by the proxy when it replaces itself.

Thank you that's right, and as you see I don't realy know Javassist.

>
> I'm using "_" to indicate "infrastructure" methods, in the believe that 
> this will not cause a
> conflict. Between that, and method overloading (by parameter type) I 
> would not be too worried about
> method name conflicts.  We should document that service methods should 
> not contain method names with
> a leading underscore (perhaps enforce that as well).

I agree and would say if there is a conflict it is enforced any way (maybe 
a meaningfull exception).

????? LifeCycle ???????

Just a few things I thought about:

> I see it as an added service model,
> by leveraging ThreadEventNotifier and a ThreadLocal, much like the 
> "threaded" service model. Also,
> there should be another lifecycle interface, like Initializable, for 
> service implementations ...
> "Passivatable"? Ugh.

Yes an additional interface would be needed (It is hard for me to find a 
good name - English is not my first language).

Actually I thought initially of two other cases: First a balance to the 
startup phase where the Registry (and all the Services) are terminated. In 
this case the user has to take care that no thread uses anymore any 
services and than he calles Registry.terminate(). All ServiceModels should 
and can be stopped in this case. I think that's currently the most 
important case for ConnectionPools etc. The second case is about 
termination of certain Services during the Runntime of the Registry.

> I'm concerned about degenerate cases; what if a service, when it 
> passivates, invokes methods on
> other services, activating them? We might need a system of locks or 
> checks to handle those cases.

I would say both (of my) cases will need a dependency-registry, which 
controls the termination and checks for circularities. If a service is 
about to be stopped all the dependend services will be stopped first.  
While I think the definition of the dependencies conceptionally belongs in 
the initializeService method I would still keep it in the hivemodule.xml 
(It is just easier to implement, because Services neither know their id nor 
the id of the services they depend on or of their Factory).

Do you think this is a possible way? Is it enough?


> Actually, much like EJBs, a service which can be pooled may be interested 
> in when it is brought out
> of the pool and brought into active service for a thread, and when it is 
> passivated and stored back
> into the pool. One interface ("ServiceLifecycle"?), two methods.
>

Therefore (and because pooling is for my cases not the same as destorying) 
I would suggest a shutdown process like this:

1) ServiceExtensionPointImpl.destroyService() -> 
ServiceImplementationConstructor.destroyCoreService(Object coreService)

2a) CreateClassServiceConstructor() -> ((Destroyable) coreService) 
.destroy()

2b) InvokeFactoryServiceConstructor() -> 
ServiceImplementationFactory.destroyCoreService(Object coreService) -> 
((Destroyable) coreService).destroy();

ad 1) The ServiceExtensionPointImpl checks if the Service can be destroyed 
now (normally only if the registry is shut down). The SEPI also remembers 
the CoreServiceImpl. The Threaded takes it from the threadlocal. If the 
threaded wants to destroy (or pool) one of its CoreImpl it calls the 
ServiceImplementationConstructor with the CoreService from the threadlocal.

ad 2a) the CreateClassServiceConstructor just checks if the CoreService 
wants to be notified of destroy and notifies it.

ad 2b) the InvokeFactoryServiceConstructor gives the coreService further to 
the Factory which created it. The Factory can now do pooling etc (the 
Pooling interface depends on the factory). The factory (if it does not 
pool) must than check if the coreService wants to be informed that it is 
destroyed (alternatively it could return a boolean indicating wheter this 
check should be done by the InvokeFactoryServiceConstructor).

    Regarding the second case (unloading a Single threaded Service during 
Registry runntime) I would say we need an extra ServiceModel. It would be 
quite similar to the deferred-model but it could also change back to the 
deferred state. It also keeps a count of threads acessing the current 
Service. When asked to shutdown it first changes to the deffered state. 
Than waits until the last thread has left the (old) CoreService and than 
does the shutdown process as described above. If the service is newly 
needed it starts it like the deffered proxy.

It would be nice if you could comment on that and I would realy like to try 
implement such a thing.



Re: [HiveMind] DeferredService performance

Posted by Christian Essl <ch...@yahoo.de>.
> Javassist doesn't do inner classes, so there's still going to be some 
> kind of _setService() kind of
> method used by the proxy when it replaces itself.

Thank you that's right, and as you see I don't realy know Javassist.

>
> I'm using "_" to indicate "infrastructure" methods, in the believe that 
> this will not cause a
> conflict. Between that, and method overloading (by parameter type) I 
> would not be too worried about
> method name conflicts.  We should document that service methods should 
> not contain method names with
> a leading underscore (perhaps enforce that as well).

I agree and would say if there is a conflict it is enforced any way (maybe 
a meaningfull exception).

????? LifeCycle ???????

Just a few things I thought about:

> I see it as an added service model,
> by leveraging ThreadEventNotifier and a ThreadLocal, much like the 
> "threaded" service model. Also,
> there should be another lifecycle interface, like Initializable, for 
> service implementations ...
> "Passivatable"? Ugh.

Yes an additional interface would be needed (It is hard for me to find a 
good name - English is not my first language).

Actually I thought initially of two other cases: First a balance to the 
startup phase where the Registry (and all the Services) are terminated. In 
this case the user has to take care that no thread uses anymore any 
services and than he calles Registry.terminate(). All ServiceModels should 
and can be stopped in this case. I think that's currently the most 
important case for ConnectionPools etc. The second case is about 
termination of certain Services during the Runntime of the Registry.

> I'm concerned about degenerate cases; what if a service, when it 
> passivates, invokes methods on
> other services, activating them? We might need a system of locks or 
> checks to handle those cases.

I would say both (of my) cases will need a dependency-registry, which 
controls the termination and checks for circularities. If a service is 
about to be stopped all the dependend services will be stopped first.  
While I think the definition of the dependencies conceptionally belongs in 
the initializeService method I would still keep it in the hivemodule.xml 
(It is just easier to implement, because Services neither know their id nor 
the id of the services they depend on or of their Factory).

Do you think this is a possible way? Is it enough?


> Actually, much like EJBs, a service which can be pooled may be interested 
> in when it is brought out
> of the pool and brought into active service for a thread, and when it is 
> passivated and stored back
> into the pool. One interface ("ServiceLifecycle"?), two methods.
>

Therefore (and because pooling is for my cases not the same as destorying) 
I would suggest a shutdown process like this:

1) ServiceExtensionPointImpl.destroyService() -> 
ServiceImplementationConstructor.destroyCoreService(Object coreService)

2a) CreateClassServiceConstructor() -> ((Destroyable) coreService) 
.destroy()

2b) InvokeFactoryServiceConstructor() -> 
ServiceImplementationFactory.destroyCoreService(Object coreService) -> 
((Destroyable) coreService).destroy();

ad 1) The ServiceExtensionPointImpl checks if the Service can be destroyed 
now (normally only if the registry is shut down). The SEPI also remembers 
the CoreServiceImpl. The Threaded takes it from the threadlocal. If the 
threaded wants to destroy (or pool) one of its CoreImpl it calls the 
ServiceImplementationConstructor with the CoreService from the threadlocal.

ad 2a) the CreateClassServiceConstructor just checks if the CoreService 
wants to be notified of destroy and notifies it.

ad 2b) the InvokeFactoryServiceConstructor gives the coreService further to 
the Factory which created it. The Factory can now do pooling etc (the 
Pooling interface depends on the factory). The factory (if it does not 
pool) must than check if the coreService wants to be informed that it is 
destroyed (alternatively it could return a boolean indicating wheter this 
check should be done by the InvokeFactoryServiceConstructor).

    Regarding the second case (unloading a Single threaded Service during 
Registry runntime) I would say we need an extra ServiceModel. It would be 
quite similar to the deferred-model but it could also change back to the 
deferred state. It also keeps a count of threads acessing the current 
Service. When asked to shutdown it first changes to the deffered state. 
Than waits until the last thread has left the (old) CoreService and than 
does the shutdown process as described above. If the service is newly 
needed it starts it like the deffered proxy.

It would be nice if you could comment on that and I would realy like to try 
implement such a thing.



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


RE: [HiveMind] DeferredService performance

Posted by "Howard M. Lewis Ship" <hl...@comcast.net>.
Took me a little bit to "get" this ... the split allows the inner proxy to replace *itself* in the
outer proxy. Clever.

Javassist doesn't do inner classes, so there's still going to be some kind of _setService() kind of
method used by the proxy when it replaces itself.

I'm using "_" to indicate "infrastructure" methods, in the believe that this will not cause a
conflict. Between that, and method overloading (by parameter type) I would not be too worried about
method name conflicts.  We should document that service methods should not contain method names with
a leading underscore (perhaps enforce that as well).

I haven't had a time to deal with lifecycle manaagement yet, but I see it as an added service model,
by leveraging ThreadEventNotifier and a ThreadLocal, much like the "threaded" service model. Also,
there should be another lifecycle interface, like Initializable, for service implementations ...
"Passivatable"? Ugh.

Actually, much like EJBs, a service which can be pooled may be interested in when it is brought out
of the pool and brought into active service for a thread, and when it is passivated and stored back
into the pool. One interface ("ServiceLifecycle"?), two methods.

I'm concerned about degenerate cases; what if a service, when it passivates, invokes methods on
other services, activating them? We might need a system of locks or checks to handle those cases.

> -----Original Message-----
> From: Christian Essl [mailto:christianessl@yahoo.de] 
> Sent: Sunday, September 21, 2003 3:44 AM
> To: commons-dev maillinglist
> Subject: [HiveMind] DeferredService performance
> 
> 
> I think the Proxy created for a deferred Service is currently 
> a bit slow, 
> because each call to a Service method first checks 
> synchronized if the 
> service is there. While the Proxy is not anymore returned 
> once the actual 
> Service is loaded I think most users of the Service will 
> still go through 
> the proxy (You know: generally early Objects live longest and 
> are most 
> used).
> 
> I would suggest the proxy to implement the GoF state pattern 
> (an idea I got 
> from commons-collection FastArrayList):
> 
> You have two proxies where the outer one contains the inner one. The 
> outerone just plainly gives further to a service field which 
> is either the 
> innter proxy or the actual loaded service. The inner proxy is 
> like the 
> current deferred proxy:
> 
> The code of a ready proxy would look like this: (This would 
> of course have 
> to be produced with JavaAssist):
> 
> public class OuterProxy implements ServiceInterface{
> 
> 	private ServiceExtenstionPointImpl _sep;
> 	private InnerProxy _inner = new InnerProxy();
> 	private ServiceInterface _service = new InnerProxy();
> 
> 	//an example method of the ServiceInterface
> 	public Object exampleMethod(Object arg){
> 		return _service.exampleMethod(arg);
> 	}
> 
> 	//the innerproxy
> 	public class InnerProxy implements ServiceInterface{
> 		//method which loads the actual service
> 		private synchronized ServiceInterface getService(){
> 			if(_service != this)
> 				return _service;
> 			_service = 
> _sep.constructServiceImplementation();
> 			return _service;			
> 		}
> 
> 		//and the exampleMethod
> 		public Object exampleMethod(Object arg){
> 			return this.getService().exampleMethod(arg);
> 		}
> 
> 	}
> }
> 
> This also prevents the - potential - method conflict that can 
> happen when a 
> ServiceInterface implements  the SERVICE_ACCESSOR_METHOD_NAME 
> (_service) 
> method.
> 
> By the way I saw this when I was looking for a way to implement basic 
> livecycle management. Have you thought of a destroy method. I 
> think it is 
> realy needed before Database, DAO, Pool, Cache, etc Services can be 
> implemented.
> 
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> 


RE: [HiveMind] DeferredService performance

Posted by "Howard M. Lewis Ship" <hl...@comcast.net>.
Took me a little bit to "get" this ... the split allows the inner proxy to replace *itself* in the
outer proxy. Clever.

Javassist doesn't do inner classes, so there's still going to be some kind of _setService() kind of
method used by the proxy when it replaces itself.

I'm using "_" to indicate "infrastructure" methods, in the believe that this will not cause a
conflict. Between that, and method overloading (by parameter type) I would not be too worried about
method name conflicts.  We should document that service methods should not contain method names with
a leading underscore (perhaps enforce that as well).

I haven't had a time to deal with lifecycle manaagement yet, but I see it as an added service model,
by leveraging ThreadEventNotifier and a ThreadLocal, much like the "threaded" service model. Also,
there should be another lifecycle interface, like Initializable, for service implementations ...
"Passivatable"? Ugh.

Actually, much like EJBs, a service which can be pooled may be interested in when it is brought out
of the pool and brought into active service for a thread, and when it is passivated and stored back
into the pool. One interface ("ServiceLifecycle"?), two methods.

I'm concerned about degenerate cases; what if a service, when it passivates, invokes methods on
other services, activating them? We might need a system of locks or checks to handle those cases.

> -----Original Message-----
> From: Christian Essl [mailto:christianessl@yahoo.de] 
> Sent: Sunday, September 21, 2003 3:44 AM
> To: commons-dev maillinglist
> Subject: [HiveMind] DeferredService performance
> 
> 
> I think the Proxy created for a deferred Service is currently 
> a bit slow, 
> because each call to a Service method first checks 
> synchronized if the 
> service is there. While the Proxy is not anymore returned 
> once the actual 
> Service is loaded I think most users of the Service will 
> still go through 
> the proxy (You know: generally early Objects live longest and 
> are most 
> used).
> 
> I would suggest the proxy to implement the GoF state pattern 
> (an idea I got 
> from commons-collection FastArrayList):
> 
> You have two proxies where the outer one contains the inner one. The 
> outerone just plainly gives further to a service field which 
> is either the 
> innter proxy or the actual loaded service. The inner proxy is 
> like the 
> current deferred proxy:
> 
> The code of a ready proxy would look like this: (This would 
> of course have 
> to be produced with JavaAssist):
> 
> public class OuterProxy implements ServiceInterface{
> 
> 	private ServiceExtenstionPointImpl _sep;
> 	private InnerProxy _inner = new InnerProxy();
> 	private ServiceInterface _service = new InnerProxy();
> 
> 	//an example method of the ServiceInterface
> 	public Object exampleMethod(Object arg){
> 		return _service.exampleMethod(arg);
> 	}
> 
> 	//the innerproxy
> 	public class InnerProxy implements ServiceInterface{
> 		//method which loads the actual service
> 		private synchronized ServiceInterface getService(){
> 			if(_service != this)
> 				return _service;
> 			_service = 
> _sep.constructServiceImplementation();
> 			return _service;			
> 		}
> 
> 		//and the exampleMethod
> 		public Object exampleMethod(Object arg){
> 			return this.getService().exampleMethod(arg);
> 		}
> 
> 	}
> }
> 
> This also prevents the - potential - method conflict that can 
> happen when a 
> ServiceInterface implements  the SERVICE_ACCESSOR_METHOD_NAME 
> (_service) 
> method.
> 
> By the way I saw this when I was looking for a way to implement basic 
> livecycle management. Have you thought of a destroy method. I 
> think it is 
> realy needed before Database, DAO, Pool, Cache, etc Services can be 
> implemented.
> 
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org