On Thu, Mar 17, 2011 at 7:22 PM, Marcel Offermans
<[email protected]> wrote:
> On Mar 17, 2011, at 18:17 , Bram de Kruijff wrote:
>
>> running into deadlocks with service registration while refactorring
>> HttpContext mechanism for the OpenSocial stuff and I am not sure how
>> to deal with it. Seen it before, it has a smell but I can not pinpoint
>> the cause and solution... Hope you can point me in the right
>> direction. This is roughly/simplified what happens as far as I
>> understand it (stacktrace below):
>>
>> DM1 tracks service registrations of InterfaceA for ComponentX
>> DM2 registers a service with InterfaceA
>> DM1 invokes callback serviceAdded(ServiceA) on ComponentX (uses a lock)
>> ComponentX invokes a method on ServiceA
>> ServiceA registers new ServiceB with DM2, again with InterfaceA
>> DM2 registers a service with InterfaceA
>> DM1 invokes callback serviceAdded(ServiceA) on ComponentX (uses a lock)
>> *DEADLOCK*
>>
>> So, if you do something in a dependencycallback that thriggers (in any
>> kind of indirect way) another service registration that results in the
>> same callback and you do any kind of synchronization in the callback
>> your are in for trouble because everything DM does is synchronous and
>> framework serviceevents are as well. Fair enough I think, but how to
>> deal with this?
>>
>> 0. The design sucks.Never have service related side effects in
>> callbacks? Seems a common enough use case though..
>
> Never ever invoke another service while holding a lock. That includes talking 
> to the dependency manager, since it will always try to directly act on 
> anything you declare, so many times, the thread you use to define some new 
> service will be used to register that service, invoke callbacks of components 
> that were listening to this service, etc.
>
> Not DM specific at all, in fact I yesterday patched a bug in the Felix 
> whiteboard http bundle that did the same (in this case it was registering a 
> servlet with the HttpService while holding a lock).

Yeah, I guessed as much as service listerners are synchronous as well.
Still wondering if a more/inherently asynchronous model (not DM
specific) wouldn't be more appropriate in the long run when delaing
with massive amount of stacked services.

>> 1. Handle callback logic (at least the stuff that has any service
>> related side effects) asynchronous? Cumbersome..
>
> Indeed, you end up launching massive amount of threads for all kinds of 
> callbacks.

I don't mind threads :) Using a centralized/managed threadpool would suffice.

>> 2. Make DM do stuff asynchronous.. why is it all synchronous? I guess
>> you could get the same scenario with bare OSGi service listeners.
>
> It's synchronous because I don't want to start new threads or use thread 
> pools all over the place. That would only slow things down and even if I 
> would make things asynchronous, I can never assume everything uses DM.
>
> So in the end I think you need to be very defensive about what you do while 
> holding a lock. In general I would say don't ever invoke something "external" 
> to your class (especially if you cannot oversee what that external component 
> will do).

Sounds like good advice for now :)

Thanks,
Bram

_______________________________________________
Amdatu-developers mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-developers

Reply via email to