Return-Path: Delivered-To: apmail-jakarta-avalon-dev-archive@apache.org Received: (qmail 13784 invoked from network); 5 Jun 2002 15:31:25 -0000 Received: from unknown (HELO nagoya.betaversion.org) (192.18.49.131) by daedalus.apache.org with SMTP; 5 Jun 2002 15:31:25 -0000 Received: (qmail 27296 invoked by uid 97); 5 Jun 2002 15:31:26 -0000 Delivered-To: qmlist-jakarta-archive-avalon-dev@jakarta.apache.org Received: (qmail 27274 invoked by uid 97); 5 Jun 2002 15:31:25 -0000 Mailing-List: contact avalon-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Avalon Developers List" Reply-To: "Avalon Developers List" Delivered-To: mailing list avalon-dev@jakarta.apache.org Received: (qmail 27216 invoked by uid 98); 5 Jun 2002 15:31:23 -0000 X-Antivirus: nagoya (v4198 created Apr 24 2002) Subject: RE: ContainerManager and Sub-containers From: Leo Simons To: Avalon Development In-Reply-To: <002a01c20c93$5071b430$ac00a8c0@Gabriel> References: <002a01c20c93$5071b430$ac00a8c0@Gabriel> Content-Type: text/plain Content-Transfer-Encoding: 7bit X-Mailer: Ximian Evolution 1.0.3 Date: 05 Jun 2002 17:34:06 +0200 Message-Id: <1023291251.4602.94.camel@hennep> Mime-Version: 1.0 X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N > > String operations can usually be cached. I know zip about > > cocoon, basically, but why is it not possible to have > > > > static String Generator.FOO_ROLE = Generator.ROLE + "/fooo"!; > > However, for most people it is just quicker to do this: > > manager.lookup (Generator.ROLE + "/fooo"); make sure you tell everyone you can influence not to! We really need that "best practices" stuff =) > The purpose of the Generator.ROLE + "/foo" is not to arbitrarily > select between several implementations of a Generator, but to > further define the _ROLE_. While not the purpose, I can see people misusing it in that way. > > > Here is something that I have been thinking about lately. > > > How can we have our cake and eat it too? How can we have a fast > > > performing component hash without the limitations of the String. > > > > 1 - don't use String (use int, long, char[]) > > 2 - cache Strings (define Strings as early as possible, > > minimise operations on String, cache operations on String) > > > > the advantage of 1 is a cleaner (smaller) implementation. The > > advantage of 2 is a more intuitive API. > > And my proposal merged the two advantages! Ehm, it merges the two solutions. > Comparison (the component may not exist): > > OLD CM > ------ > TestComponent myComp = null; > > try > { > myComp = (TestComponent) manager.lookup( TestComponent.ROLE ); > > myComp.doSomething(); > } > catch (ComponentException ce) > { > getLogger().error("Missing component", ce); > } > finally > { > if (null != myComp) manager.release( myComp ); > } > > > NEW CM > ------ > Request req = manager.createRequest( TestComponent.ROLE ); > > if (null == req) > { > getLogger().error("Missing component"); > } > else > { > TestComponent myComp = manager.lookup( req ); // guaranteed to be > there > myComp.doSomething(); > manager.release(myComp); > } basically, you substitute exception handling for a test against "null". This is not an advantage. good: doAction() throws ActionException { ActionHandler handler = null; try { final ActionHandler handler = (ActionHandler)m_manager.lookup( ActionHandler.ROLE ); final Object result = handler.doSomething(); m_manager.release( handler ); return result; } catch( ComponentException ce ) { getLogger.error("Missing Component", ce); throw new ActionException("Sorry!", ce); } // no need to release handler if a ComponetException occurs } as opposed to: doAction() { final ActionHandler handler = (ActionHandler)m_manager.lookup( ActionHandler.ROLE ); /* no reason we can't drop the exception in this method if we want */ if( null == handler ) { getLogger.error("Missing Component"); return null; // no need to release handler if there is none } final Object result = handler.doSomething(); m_manager.release( handler ); return result; } or: doAction() { final Request request = m_manager.createRequest( ActionHandler.ROLE ); if( null == request ) { getLogger.error("Missing Component"); return null; } final ActionHandler handler = (ActionHandler)m_manager.lookup( ActionHandler.ROLE ); final Object result = handler.doSomething(); m_manager.release( handler ); return result; } Exceptions are _good_. try/catch is better than if/else in cases like this. > We saved three lines of code, and increased readability and > comprehensibility > of the code at the same time! I disagree. See samples. > By three lines of code, I am counting > every > line that has text (excluding comments and blank lines). As for > complexity analysis you add one for every block of code (i.e. every time > you > have a new bracket). We even saved here. The exception-based method has two (one for try, one for catch), the non-exception-based string method has one, and the request-object-based method has one. However, I think complexity doesn't really increase when using exceptions. The use of the request object does not reduce complexity, though. > > How often do you need to server millions of requests a day > > where the bottleneck is not somewhere else? > > 9 times out of 10, the problem is in synchronization between many > different > threads. The ECM is one major source of thread contention issues. > Fortress > is proof that by removing as many chances for thread contention as > possible > dramatically increases the speed in which you can resolve requests. > > Using the Request based component resolution, we gain further benefits > by > the ability to arange the components in any fashion we wish. We could > put > them all in an array for all we care. There won't need to be any > synchronization unless we replace an entry. We can further increase the > speed of the whole system. Is this not possible in a way completely internal to the CM? > > /** > > * Keep current method, basically making the call to > > * createRequest internal. Also means these changes can probably > > * be done somewhere in a future avalon 4 release as no existing > > * functionality is removed or changed. > > * Note that the CM could still do some smart caching of the > > * generated Request objects internally. > > */ > > Object lookup( String role ) throws RuntimeException; > > To maintain compatibility it would be ComponentException--not > RuntimeException. gotcha. What I ment. What I see: You think there are many cases where string creation or string hashing are the bottleneck for a system that needs performance. You propose to use a request object for the CM, basically a container for a long, to solve this. The request object is then retrieved, using string creation and string hashing, from the CM. I think the bottleneck is usually elsewhere. I propose to leave the responsibility for optimisation outside of the ComponentManager interface. If the request object is not cached by the user, there is little performance gain. If the user is smart enough to cache the request object, he is probably also smart enough to cache the lookup string and the requested component, meaning there is no bottleneck. did I miss something? - Leo -- To unsubscribe, e-mail: For additional commands, e-mail: