Schaible, J�rg wrote:

Hello Steve,


Looking at the Avalon framework itself, it seems to offer a
simple, but mighty base for a service infrastructure. With "Developing with Avalon" (DwA) a nice documentation exists, although it refers ECM. "Although", because running Avalon 4.1.3 and Excalibur 4.1.3, a lot of deprecated API of the Avalon framework is accesed by ECM. At this stage I asked myself for the first time, if am I going into the right direction.

I think your going in the right direction! The real benefit kicks in what you stop thinking about the component construction side. You can forget about dependencies completely - forget about what lifestyle a component supports, forget about complex configurations and setting all of this up. You can also forget about the potental for runtime failures due to component depedencies that cannot be resolved (because all of the above is handled automatically for you).

OK, I burn the DwA <g>

Nah, .. we just need to bring it up-to-date :-)


[...] E.g. for the running merlin demo: How can I access now the services?
You don't!

Ahhh, this is it <g>


Ok - that needs some explination :-)
Keep in mind that for the moment your thinking from a coontainer side perspective. You have established the kernel which means that your component logic is established. There is nothing more you need to do. The rest of the story unfolds on the component side. You components (which will be activated as needed) just interact with classic context, configuration, service management artifacts.

OK. So the kernel's task is to identify the components, installs and loads them and expects then, that the application is running. Well ...


I just have a DefaultKernel object, but somehow I am missing
the factory class.

There have been a bunch of changes introduced recently concerning service reference expressed as URLs. There were some issues with the initial implementation that caused conflicts with Tomcat. The result is that the URL management model is being totally rewritten. The URL generation side is now implemented in the assembly package - but service resolution using URLs is still in progress. This is not a problem when Merlin is triggering component activation - but in your case your in a Servlet which isn't under control of Merlin. This is where service URLs come in - you servlet will (in the near future) simply request the service it needs using a service URL and Merlin will take care everything necessary to establish that service.

... now the things are becoming clear ... and my concerns are growing <g>.
LOL

The URL analysing service is something we already have and I will havo integrate this into the webapp. So I assume I had to modify some of the DefaultXXX classes to convert my servlet into something that is part of the component logic.
In principal you should not need to extend anything (at least tha't the objective). The URL side really only comes in play when the servlet is handling dynamic content presentation. An HTTP request can include a service identifier and parameters. The servlet directs the request to a service running in Merlin which can then handle the request resolution. This works really nicely and makes for really compact code in the web-app - but more about this later in the week.

But, my real concern is the current implementation scheme. If I have a webapp I have 95% of the time a simple request/response task. Normally I would handle each request in one thread unless I have to access something in the back-end or have a long-running calculation. But with Merlin I seem to have a lot of running threads communicating with each other for every single request.
Not following this. Merlin creates one thread per container so I don;t see where the "lots-of-threads" is comming from. If you running one thread per request you may want to look at the per-thread lifecycle policy. This policy ensures that a new component instance is created once per-thread. There is an example of the per-thread componet in the playground. Default lifestyle behaviour is singleton (i.e. thread safe componet). To declare a per thread policy all you need to do is add an attribute to the .xinfo file for the component you want to be per-thread. Here is an example:

<type>
<info>
<name>my-component</name>
<attributes>
<attribute key="urn:avalon:lifestyle" value="thread"/>
</attributes>
</info>
</type>



I am asking myself if this is performant. The application will have to do a lot of unnecessary synchronization overhead.

The only occasion where you have cross thread synbchronization is when you have a component that is a singleton and that component is providing services to other component running in other threads. The extent to which this happens is totally under your control because you can control the structural layout of compoenents withing the block implementation definition - and you control lifestyle for component types.

But maybe I'm missing the issue?


An appliance is an object that a container implementation uses to manage component instantiation. It takes care of two aspects of component establishment - lifecycle and lifestyle. [...]
Keep in mind that the appliance abstraction is something you should not need to be concerned with unless your planning on doing something that cannot be expressed using xfiles (which would be unusual).

Well, then I assume, that the appliance tag in block.xml just describe which appliance is used to establish the component itself ... right?

Yep - if you don't declare and it turns out that Merlin needs a particular appliance to satisfy a dependency, then merlin will automatically establish an appliance for you. The applicance declarations are simply to (a) add explit control over the information used to establish an appliance - e.g. extra configuration or context information, and (b) control visibility through containment at different levels in the container hierachy.

If the type manager does not know about your component - then its because (a) you have not defined a <component-class>.xinfo file. The type manager will attempt to create this for you providing the .xinfo exists - if it does not then the type manager does not know its a component. In the log you should see information from the type manager as it registers know components - if you component is not being listed - it means that it is not being recognized as a compoent.


<block>
<implementation>
<appliance name="standard" class="demo.service.HelloWorld" activation="startup">
<context class="demo.service.HelloWorldImpl"/>
<configuration>
<message>Hello World block descriptor.</message>
</configuration>
</appliance>
</implementation>
</block>


No problem with the above providing your component has an .xinfo file associated with it.

Well, it's case a) - it does not have an .xinfo yet <g>. I'll give it a try.

Just for reference - case (b) was non-discovery of the component because of non-discovery of the jar file - but that will not be a problem because the engine automaticaly scans all of the jar files in the classloader heirachy when first initialized.

[...] I am currently working on the block implementation stuff related to service URL exposure (should be done around the end of the week). This will allow imcomming HTTP requests that include service references (together with queries, refs, etc.).


Looking at the time I already spent and the results I
reached, I am currently really somewhat frustrated. Any help welcome ...

I'm guessing this is a missing .xinfo. If that does not fix the problem please post a log of the activity with system debugging enabled.

Your guess was right - but here comes another issue ... how to enable the system debugging? It seems that the component establishment has another log level.

From the command line

$ merlin -debug

From an embedded scenario - when you contextualize the kernel you can control the default logging priority by passing in a conext entry "urn:merlin:debug" - with a value of a String with the logging priority level (e.g. "info", "warn", "error" or "debug"). The command line -debug option just passes in the "debug" string to the DefaultKernel context.

Apart from that you can control logging priority for any appliance or block declared in your blocks.xml file using the <categories/> element.

<categories priority="WARN"/>

The above declaration set the logging priority for whateve is enclosing it to the declared level. In the following example the logging level is set to INFO and a child logger called my-sub-channel is set to DEBUG.

<categories priority="INFO"/>
<category name="/my-sub-channel" priority="DEBUG"/>
</categories>

Here is a practical example in which I'm setting different logging levels at the block and appliance levels.
<block name="demo">

<implementation>
<!-- set the logging level for the root block to WARN-->
<categories priority="WARN"/>

<appliance name="standard" class="org.apache.avalon.playground.StandardComponent" activation="startup">
<!-- set the logging level for this component to DEBUG -->
<categories priority="DEBUG"/>
</appliance>

<container name="test">
<!-- set the logging level for this container to ERROR-->
<categories priority="ERROR"/>
<appliance name="standard" class="org.apache.avalon.playground.StandardComponent" activation="startup">
<!-- set the logging level for this component to INFO -->
<categories priority="INFO"/>
<context class="org.apache.avalon.playground.StandardContextImp"/>
<configuration>
<message>Standard component inside a nested block.</message>
</configuration>
</appliance>
</container>

</implementation>

</block>

Regards and thanks for your explanations,

No problem - the feedback makes it worthwhile ;-)

Cheers, Steve.

J�rg

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




--

Stephen J. McConnell
mailto:[EMAIL PROTECTED]
http://www.osm.net




---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to