On Mon, Jul 26, 2010 at 1:27 AM, William Tam <email.w...@gmail.com> wrote:
>
>
> On 07/25/2010 01:56 PM, Claus Ibsen wrote:
>>
>> On Sun, Jul 25, 2010 at 6:18 PM, William Tam<email.w...@gmail.com>  wrote:
>>
>>>
>>> Hi Claus,
>>>
>>> Thanks for your response.
>>>
>>> * A ProcessorEndpoint is a hybrid between a Processor and a Endpoint.
>>>  Therefore, SendProcessor does have a child if the destination is a
>>> ProcessorEndpoint.  Please take a look at
>>> RouteService.doGetChildServices().
>>>   You will see why Navigate can allow services associated with the
>>> ProcessEndpoint to be restarted.
>>>
>>>
>>
>> No it does not have a child. It sends a message to an endpoint, period.
>>
>> The processor endpoint is just an endpoint which uses an processor
>> where end users implement the logic what should happen when the
>> message is being sent to it.
>>
>> > From the route perspective the message is sent to an endpoint, no
>> matter what. How and where that endpoint is, should not be part of
>> navigate. Navigate is to be able to traverse the route graph deployed
>> in the camel context. For example to be used by tooling or the likes.
>>
>
> OK, I don't really care whether it has a child or not (whatever that means).
>  RouteService.doGetChildServices() is traversing the children using the
> Navigate interface in order to start all of their services.  It is wrong in
> RouteService method that starts all the children services by using Navigate
> interface then?  This is the only way the services associated with the
> ProcessEndpoint can be restarted.   Or, you are suggesting ProcessEndpoint
> should not implement Service since there is no guarantee the service will be
> restarted by design?
>

Yes I agree that ProcessorEndpoint should be a Service so it has the
start/stop methods, you can leverage.
In fact the Endpoint should be a Service so all endpoints is being
started/stopped when you restart CamelContext.
I am working on adding this right now.


>>
>>
>>
>>
>>>
>>> * Yes, when I say 'type converter", I mean the DefaultTypeConverter.
>>>
>>> * If I am not mistaken, ShutdownCompleteAllTasksTest is one example that
>>> the
>>> DefaultTypeConverter was accessed after the DefaultTypeConverter has been
>>> shutdown.
>>>
>>> * I think you are against lazy loading of DefaultTypeConverter.  I am
>>> fine
>>> with that.  Then, we should really get rid of the lazy loading (in
>>> DefaultCamelContext.getTypeConverter).   That is really what the problem
>>> is
>>> because since it is a service, it gets stopped but the lazy loading does
>>> NOT
>>> re-start it.  (Maybe you just fixed it.  I haven't got a chance to try
>>> it.)
>>>   And believe me, having both (a Service and lazy load and start) is
>>> troublesome.
>>>
>>>
>>
>> No the problem is that James S. named the method
>> forceInitLazyService() or something (the name is
>> forceLazyInitialization)
>> The type converter is started when CamelContext starts. And in essence
>> its not lazy. The getter appears to be lazy because you can plugin a
>> custom type converter registry and therefore the default instance is
>> created only if no custom has been assigned.
>>
>
> I (or anyone) can tell that DefaultContextContent.getTypeConverter is
> definitely doing lazy initialization. See it for yourself.  :-)  Yes, I know
> getTypeConverter() is called when the CamelContext is started but this is
> not the only place getTypeConverter() is called.  So, the first time it is
> called, the type converter is created.  In some cases (although mainly unit
> tests), getTypeConverter() is called without CamelContext started is called.
>
> public TypeConverter getTypeConverter() {
>        if (typeConverter == null) {
>            synchronized (this) {
>                // we can synchronize on this as there is only one instance
>                // of the camel context (its the container)
>                typeConverter = createTypeConverter();
>                try {
>                    addService(typeConverter);
>                } catch (Exception e) {
>                    throw ObjectHelper.wrapRuntimeCamelException(e);
>                }
>            }
>        }
>        return typeConverter;
>    }
>
> You can also see addService() (which starts typeConverter) was only called
> when a typeConverter was created by createTypeConverter().  Therefore, when
> you restart the CamelContext, addService() is not called and therefore
> typeConverter is not started.   My point earlier was that combining lazy
> initialization and addService() is troublesome.  (I have not yet read your
> latest fix though).
>

This has been fixed. I commented this on the JIRA ticket

Claus Ibsen added a comment - 25/Jul/10 03:28 AM
trunk: 978994.
I have fixed the issue in CamelContext to re-initialize type converter
registry on restart



>> The fix will no ensure CamelContext will start the type converter if
>> CamelContext is started again.
>> I checked that it worked using the TimerRestartTest unit test.
>>
>>
>>
>>>
>>> * IMO, If DefaultTypeConverter is a Service, it should not be usable
>>> (throw
>>> an error something) in the "stopped/not started" state when someone tries
>>> to
>>> use it.  Accessing a stopped DefaultTypeConverter is bad to say the
>>> least.
>>>  You don't get an error, you just get different/wrong result.
>>>
>>>
>>
>> Well you often use a producer/consumer and access type converters from
>> those. The producer/consumer should have been stopped before the type
>> converter (as its one of the last to be stopped). So your logic in the
>> producer/consumer should have caught that we have stopped.
>>
>
> At least, the "system utils" stuffs like type converter should be the last
> to be stopped.  Just adding to servciesToStop List is probably not ideal.
>>
>> And there are zillion ways you can access stuff in Camel and we can't
>> be police men and add isStarted() checks everywhere.
>>
>
> Ideally, type converter should not be stopped (i.e. not a service).  So,
> callers can guarantee getting consistent results.
>>
>> You just hit a issue with restarting an application which is really
>> hard to do reliable.
>> The best way is to re-create CamelContext to ensure all can be started
>> nicely again.
>>
>>
>
> The CamelContext should be able to start, stop and re-start robustly.  I
> don't think we far from there but these issues should be addressed correctly
> if we want to get there.
>>
>>
>>>
>>> Cheers,
>>> William
>>>
>>>
>>> On 07/25/2010 02:46 AM, Claus Ibsen wrote:
>>>
>>>>
>>>> On Sun, Jul 25, 2010 at 5:55 AM, William Tam<email.w...@gmail.com>
>>>>  wrote:
>>>>
>>>>
>>>>>
>>>>> I observed some issue regarding restarting Camel Context that I want to
>>>>> discuss.  The detail is in the CAMEL-2991.
>>>>>
>>>>> * First off, any objection if SendProcessor implements Navigate?  It
>>>>> allows
>>>>> services associated with the destination endpoint to be restarted.
>>>>>
>>>>>
>>>>>
>>>>
>>>> Why does navigate allow services associated with the destination to be
>>>> restarted? Can you be more clear?
>>>>
>>>> The idea with navigate is for navigating the process graph.
>>>> For example a Content Based Router, where you can navigate the
>>>> when/otherwise processors etc.
>>>> A SendProcessor doesn't have any "children" to navigate, and therefore
>>>> should NOT be navigate.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>>
>>>>> * There is a problem with type converter not getting restarted because
>>>>> the
>>>>> lazy instantiation won't start the services on the type converter
>>>>> unless
>>>>> the
>>>>> type converter is newly created.  I notice (in a lot of unit tests)
>>>>> that
>>>>> it
>>>>> is OK to use the type converter even if the CamelContext (its
>>>>> "container")
>>>>> is stopped or has never been started.  If we want this behavior, then
>>>>> it
>>>>> does not seem to make sense for type converter to be a service.  Type
>>>>> converter could be used anytime including during the shutdown cycling.
>>>>>  Since type converter has been added to the "servicesToClose" list, the
>>>>> type
>>>>> converter could be stopped (unpredictably) when it is needed during the
>>>>> shutdown cycle.  IMO, type converter probably should not be a service.
>>>>>
>>>>>
>>>>>
>>>>
>>>> I assume you mean the DefaultTypeConverter ?
>>>>
>>>> The DefaultTypeConverter must be a Service so CamelContext can
>>>> start/stop
>>>> it.
>>>> It's important that it's the CamelContext that starts it on startup so
>>>> all the type converters can be loaded up-front.
>>>> Then there is no lazy loading.
>>>>
>>>> The problem with a lazy loading would be at runtime you can end up
>>>> with concurrent access to the type converter registry
>>>> and then multiple threads need to load the type converters, which
>>>> enforces locking/synchronization. And you don't want this overhead
>>>> at runtime. Hence the converters are loaded on startup.
>>>> And to do this the DefaultTypeConverter MUST be a service so we have
>>>> the start/stop methods.
>>>>
>>>> There is no strict check in several places of the code to check that a
>>>> "service" is started before its being used.
>>>> And therefore you can access code which has been stopped.
>>>>
>>>> Can you give an example of an unit test, which uses a type converter
>>>> after CamelContext has been stopped?
>>>>
>>>>
>>>> And when you say type converter you have to be more precise. There is
>>>> a TypeConverterRegistry and then there are the 150+ individual type
>>>> converters.
>>>> The former is the DefaultTypeConverter which loads all the type
>>>> converters. The latter is most often not a service because they are
>>>> @Converter scanned.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>>
>



-- 
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus

Reply via email to