> -----Original Message----- > From: David Leangen [mailto:[EMAIL PROTECTED] > Sent: Sunday, August 01, 2004 14:23 > To: Avalon framework users > Subject: RE: Using time-consuming services from a component > > > Guys, > > Thanks again for discussing all this with me. > > Let me explain in a little more detail what I'm doing here. Currently, I > am > at the beginning of a meduim-sized project. At this point, I'm just > investigating various issues. What I'm interested in doing is making the > project component-based, so I'm investigating what technology to use to > accomplish that. I'm also looking at how to build the framework, the goal > being to add a little overhead to greatly simply the system as a whole. > From > a business perspective, I'm looking at trying to lower costs, promote > reuse, > and so on. Eventually, if things go well for this project, we'll reuse the > same approach for the entire company. > > Essentially, the project consists of various models that may or may not > interact. A model ranges from trivial to complex. Now, to understand the > vocabulary I'm using, and to simply things a little, let's suppose that > each > model has a Manager, and this Manager is a POJO. So, for the n models in > the > system, there will be n POJOManagers. (Of course, this is a vast > simplification, but it will do fine for this discussion.) > > What I mean by "service" is using an Avalon component as an adapter to > each > POJOManager. (After all, a model provides a service, even if it's just > changing the state of something...) So, by my reasoning and using this > simplification, if we want to "Avalonize" the entire system, there will be > n > ServiceProviders, each acting as an adapter to a POJOManager. > > Now the fun starts. You see, for me, the promise of Avalon is being able > to > mix and match the various services (using my definition above) as > components. In other words, a component comprises one or (probably) more > services. The developer should be easily able to grab any combination of > services to quickly put together any kind of component. In fact, > components > could also be composed of other components. > > So far, I think this is what Avalon/Merlin is intended for. > > > When dependencies are clear, everything works beautifully! Each service > will > fire the services it depends on and all goes amazingly well. > > > Where things get messy, however, is when you want to build components from > services that should NOT be dependent, but you want the services to > execute > sequentially. (For a good comparison of what I mean here, think, for > example, Ant tasks and they are executed sequentially.)
What your describing here is a something like a workflow. For example an ant buildfile contains a set of targets where each target contains a set of serial (or possibly parallel) tasks. The notion of Task in Ant is loosely equivalent to the notion of Component in Merlin. What is interesting is to compare the respective abstractions. In Ant, Task and DataTypes are the building blocks that are using within buildfile - the buildfile is the workflow definition. Merlin does not provide a workflow definition - instead that would the concern of a workflow component. Ant | Merlin -----------------|------------------------------------------------ Project | ? Target | ? Task | Profile (Component or Container) | Block | Component | Type | > It appears that this can be done, but it's not what Merlin was intended > for, so the solution is a hack. Merlin does not provide a workflow or sequencing model. Its focus it composition. In merlin a workflow of activity sequencing solution would be modeled as a component and merlin would take care of the concerns related to composing the things that the component needs to function properly, e.g. a scheduler, a script, maybe an execution context, a reporting system, etc. I think the important thing to bring out here is that a block is not a sequence in any shape or form - its simply a description of the essential aspects of a composition that merlin uses as part of its deployment process. A workflow would be modeled as a completely separate abstraction (although I can understand how one could think about using one for the other as many of the things you would describe would look very similar). > Out of the possible solutions that have been > suggested to me are: > > 1. Declare artificial dependencies. This does solve the problem, > but it creates a spaghetti of artificial dependencies that > just shouldn't exist. To me, the whole point of using a > component model is that each component should be independent. > In the extreme, that means that I'll have to declare every > component dependent on every other component, just to be > sure. That makes no sense! Dependencies in merlin are structural dependencies. I have the feeling (in fact I'm certain) that you are describing execution ordering. Within ant there is a separate abstraction to deal with this - the 'target'. Let's imagine that you have a component called a 'finder' and that the finder does that stuff of locating component you need in your script. Let's also assume that your script is managed by a workflow component and that the workflow component has a structural dependency on a finder in order to find the components to execute. <component name="workflow" type="WorkflowComponent"> <configuration> <sequential> <job name="first-job"> <!-- stuff --> </job> <job name="second-job"> <!-- other stuff --> </job> <sequential> <configuration> </component> > > How can you listen to a component that you don't "know about" (i.e > > no dependency). Please note that the dependency can be declared both > > optional and against very generic interfaces. > > I think what I didn't explain well here is that, reusing my definitions > above, my Component will use two ServiceProviders. So, of course the > Component will "know about" the ServiceProviders, but each ServiceProvider > should not need to know anything about the other. I'm guessing that your service providers should be modeled as Executable components, not startable/stoppable components. I also think this differentiation is a result of a non-clarity in the docs - in particular I think we need to more start/stop out of the launch phase and into the management phase - and in the management phase we need to present the two distinct abstractions - Executable and Startable. I also think we should revisit the principal of allowing startable components in a kernel context that is set for execute model (but this is more a subject for the dev list). > In any case, the thing is, to me "optional dependency" is an oxymoron. > Either there is a depedency or there is not. A dependency cannot be > "optional". If it were optional, than there is no dependency to begin > with! Let's assume that you have a component that includes some logic to get information about latest updates. To do this it needs a network connection and a bunch of related stuff. But lets assume that the network can be assumed to be down for whatever reason, but the functionality does not change simply because the network connection cannot be established. In this scenario the 'update-available?' service is optional. Optional means more flexibility in terms of a component's ability to do it stuff independently of the context it is running within. > Also, declaring to a more generic interface makes sense... but isn't that > what the component-based model in intended for to begin with? > > > 2. Use an event listener to wait for the completion of the services's > execution. Ok, but shouldn't the framework be doing this for me? > What's the point of having a nice framework if I have to go and > make while loops while waiting for an event? This also complexifies > the code, which is not something I want to get into. I think this is getting back to the question - should be you using Executable.execute() as opposed to Startable.start()? I figure you application problem is calling for the former. > 3. Make a new service interface for each sequence. Say that in my case, > I have ServiceProviderA (which, we remember, is an Avalonized > POJOManager, > that I want to execute before ServiceProviderB. Well, I could make > a ServiceProviderAB, which, like ServiceProviderB, is an Avalon > component adapter for POJOManagerB, but this time actually > declares a dependency (since one arguably exists in this particular > scenario). > > But again, with this approach, we'll end up with a gazillion components, > complexifying the system and making things worse, not better. In any case, > I > feel uncomfortable with this approach. > > > 4. Make a Component that simply directly uses the POJOManagers, rather > than the ServiceProviders. Well, again, this defeats the whole > purpose of using the ServiceProviders, doesn't it? > > > All these work, but none are desireable. Really, the best situation is to > have, within something like the Executable interface, a way of making a > call > like: > > execute() > { > executeAndWait(serviceProviderA); > executeAndWait(serviceProvicerB); > } > > Or perhaps: > > execute() > { > execute(serviceProvideA).execute(serviceProviderB); > } > > Or maybe: > > execute() > { > executeSequentially(serviceProviderA, serviceProviderB); > } > > Or whatever. > > > THAT would be sweet!! This is basically the difference between executable and startable. > But since that doesn't exist, either I'll have to choose one of the above > hacks, or give up on Merlin. I don't want to give up on Merlin, but I > don't > really like any of the workarounds I've seen so far. So it looks like I'm > SOL. Sucking on a Lollypop? > > Somehow I have the feeling that you are just trying to fool around > > to get grips with the concepts, and perhaps not very comfortable > > with the way we do things in Avalon. If you are trying to give us a > > simplified view of a real-world problem, perhaps it is better if > > you give me the 'reality' and explain what you try to do, and I'll > > tell you how to go about it. > > You are correct. As I explained above, I'm still trying to imagine the > long > term effects of refactoring the entire project (and eventually the whole > company) to use Avalon. Will this LOWER costs or RAISE them? At this > point, > I'm not so sure... Just based on a lot of code and a lot of projects - it will lower the cost somewhere between 60-80%. The percentage comes as a result of understanding what to do when, combined with the development and runtime products. Walking into a classic java shop .. getting 60% improvement is straightforward. Timeframe depends on the number of people - but for example, a team of about 50 people, getting a 60% improvement is maybe a six month process. Cheers, Steve. > So, at this point, other than my tests, I am indeed speaking relatively > theoretically. > > > Thanks again for the help! > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]