Peter Donald wrote: > On Wed, 2 Oct 2002 00:54, Berin Loritsch wrote: > >>Issue #1: Component Lookup/Release >>---------------------------------- >> >>Part of what the ComponentSelector solved was the need for lookup and >>release mechanisms. Simple types cannot provide release mechanisms, >>so only ThreadSafe components can be safely used with simple types. >>In the Phoenix realm, that is not a real problem as most services are >>ThreadSafe anyway. However, at lower levels (i.e. Avalon embedded >>in another container hierarchy like Servlets) developing all components >>as ThreadSafe is not always practical. We need transient components. >> >>Since the solution we come up with must work in the general case, the >>compromise was the ComponentSelector--something that Peter D. regrets >>to this day ;p. > > > :) > > >>In order to fully get away from the need of the *Selector interface, >>we need a way to mask the component management for transient components. >>One way is through dynamic proxies that will pull an instance from >>a pool as needed, and will automatically return it after a specified >>period of inactivity. The major issue is managing state information. >>In order to work with transient/stateful components we need a session >>mechanism so that a component can store its state in the session so >>the client will never be the wiser. > > > Wait for Interceptors - they be magic. Request, Session and Application scopes > are what I am using now and they work brilliantly. The only problem is that > each call incurs too much overhead atm ;( > > Its a work in progress but needs to be completely rewritten with BCEL at each > end to get required speed. > > >>BTW, for the benefit of all who weren't around the last time we had >>the many components for one role discussion, a Releasable interface >>was vetoed. I proposed adding a method like "release()" to the >>component interface that would provide real semantics for having a >>Component interface as well as not requiring release() on the >>CM/CS interfaces. I think I was the only one in favor of that at >>the time. > > > I have completely changed my mind. I think something like the following is the > way to go. > > interface Releaseable > { > void release(); > } > > The magic thing about what I am going to propose in about amonth is that no > component will ever implement this interface ;)
So is it something that will always exist? IOW, how would the user releae it? > Lets assume that every component is exposed via a proxy with an interceptor > chain attached to it. So when you invoke a method it will be passed through > each interceptor in chain. > > Just say our chain looks something like > > Service Interface > | > v > Pooling Interceptor > | > V > Target Method *!A light bulb goes off over my head!* If we have sessions, etc. then the proxied interface performs the release() and the client never sees it! That would rock! > Now lets just say that our pooling interceptor looks something like > > > Object invoke( Invocation i, InterceptorContext ctx ) > { > if( i.getMethod() == m_cachedReleaseMethod ) > { > ObjectPool pool = (ObjectPool)ctx.get( ObjectPool.KEY ); > Object object = ctx.remove( InterceptorContext.TARGET ); > pool.release( object ); > return null; > } > else > { > return ctx.invokeNext( i, ctx ); > } > } > > So what does this mean? This means that the proxy implements the Releaseable > interface but the underlying object doesn't and in fact may not even know > that it is being pooled. When you call release on an object the call never > makes it to the target object but is intercepted and handled by the > interceptor that grabs target object, removes it from correct context and > places it back in the pool. (The correct context being related to how > sharable the object is). Here's me salivating over this future feature. ;) >><dependencies> >> <dependency> >> <service name="org.apache.MyService" as="#"/> >> </dependency> >></dependency> > > > That was how I originally implemented it today but it introduced more > complexity into the code and into documentation. Part of this is because of > BlockInfo format (Service is shared between service publishing declaration > and service dependency declaration). Effectively the above is same as > > <dependencies> > <dependency> > <role>org.apache.MyService</role> > <service name="org.apache.MyService[]"/> > </dependency> > </dependency> Ah. That is in contrast to the "Meta" package (Stephen's baby) which has a distinction between ServiceDefinition and ReferenceDescriptor. IOW, a Dependancy is separate from the service definition. I like the Service being a first class item (is that done for Phoenix?), and then using a reference object when looking it up. The difference is really minimal. >>void service( ServiceManager sm ) >>{ >> Map services = (Map) sm.lookup( Service.ROLE ); > > > I still prefer the convention that key coresponds to type if unspecified > rather than coresponding to component type and thus even if following the > convention Service.ROLE could return a Map, Selector or Array depending on > the host component. I much prefer a simpler one to one mapping like > > Service service = (Service) sm.lookup( Service.ROLE ); > Service[] service = (Service[]) sm.lookup( Service[].class.getName() ); > > //Next line different as java no have associative arrays > Map service = (Map) sm.lookup( Service.ROLE + "{}" ); Yes, but as long as you don't *force* it to be like that, it is ok. I am seeing the value of being able to name my components whatever I want, and the container resolving them for me. >>At assembly time, we specify them like this: >> >><block class="org.apache.MyComponent" name="myComp"> >> <provide name="service1" role="org.apache.MyService"/> >> <provide name="service2" role="org.apache.MyService"/> >> <provide name="service3" >> role="org.apache.MyService" >> alias="myAlias"/> >></block> > > > Again - it does not make it any clearer in my opinion to make the > interpretation of role context sensitive. Yes, but the fewer places we declare the array/map/selector requirement, the better. Imagine this scenario: <dependency> <service name="org.apache.MyService{}"/> </dependency> --------------------- <block class="org.apache.MyComponent" name="myComp"> <provide name="service1" role="org.apache.Myservice[]"/> <provide name="service2" role="org.apache.Myservice[]"/> <provide name="service3" role="org.apache.Myservice[]"/> </block> ---------------------- What is the type? It is important to note that the dependency is declared as a Map ("{}") and the assembly is declared as an array ("[]"). I would also like to bring up at this time that with certain fonts there is little visual difference between curly braces and square brackets. The "#" was better, but the angle brackets were also acceptable. Does the container throw an error? Does it provide an array, and the component code throws a ClassCastException? Or does it ignore the designator in the assembly file and use what was declared in the blockinfo? If it is the last option, then I wouldn't put any designation in the provide section. >>I would even go farther and say that we >>would be able to remove the necesity for the role="..." attribute in the >>assembly if the component only implements one role. > > > yep. 99% of assembly.xml can be autogenerated with a smart enough bit of > discovery code. Which means its verbosity can be reduced quite a bit. -- "They that give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." - Benjamin Franklin -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>