On 2016-08-08T09:48:49 +0200 Peter Kriens <peter.kri...@aqute.biz> wrote: > > Correctness before performance.
That's a sentiment I can get behind. For the purposes of the discussion: I'm not interested in the performance implications of the subject we're discussing, only the correctness issues. > The trick in my experience is to write your code as simple as possible given > the previous model. Disregard bundle boundaries. Bundle updates are rare and > imho irrelevant for general performance. Once you got your system working > correctly measure the activation performance. If you then have a problem the > solution then usually stands out rather clearly. > > One solution then is to register the service manually. If you have a very > lengthy initialization then you can create an immediate component without a > service. In the activate method you just start a thread that does the > initialization and when it is done you register the service via the bundle > context you got in the activate method. This same pattern can also be used > when you have to watch a condition (network online for example). You watch > the condition and then you register/unregister the given service. > So the problem here is that a service S wants to acquire a global resource R and that takes time to acquire. It also needs to give back R when it's done, and that takes time to release. Let's examine the two possible cases with regards to blocking or non-blocking activation/deactivation: If S _isn't_ allowed to block in activate()/deactivate(), then the resource R may not have been acquired by the time activate() has returned, and may not have been released by the time deactivate() has returned. The problem then is that when the bundle containing the service is restarted, the old instance of S is almost certainly still in the process of releasing R, and so the new instance T crashes when it tries to acquire R on activation. This leaves S not running because it's just been deactivated, and T not running because it couldn't start. This seems to be impossible to solve in general without using something static that can survive bundle restarts and that can serialize the operations. It doesn't matter how many indirections of services are added that can wait for initialization and then register services, the same problem remains for those services too [0]. All adding extra services does is punt the problem around to elsewhere in the system. Using static is obviously a big NO in a system like OSGi, so that's not a good solution. However, if S _is_ allowed to block in activate()/deactivate(), then the problem appears to be solved with one major caveat that the specification seems to specifically not address: I think the specification allows OSGi implementations to call activate() on a new instance T _concurrently_ with calling deactivate() on the old instance S. At least, I don't see anywhere in the spec where this is disallowed. If so, it seems that we're depending on unspecified implementation-specific behaviour to prevent bad things from happening. This view may actually be supported by something you said (emphasis mine): > In my experience, OSGi significantly changes the landscape concerning > initialization. You get lots of local small initializations that are > _automatically parallelized_. For example, it seems as though it's perfectly permissable for the runtime to call deactivate() on an old instance of a service and to also concurrently call activate() on a new instance of the same service. We're back to square one: The new instance attempts to acquire R and can't, while the old instance is still in the process of returning R. It doesn't matter if activate()/deactivate() are blocking or not. M [0]: You may notice that back in my original email, I stated that my TCPServer example actually doesn't export any services at all, it simply forwards data from the network to an existing service, so it's not a question of delaying the registration of a service in that specific example.
pgpvMKg4JsAnh.pgp
Description: OpenPGP digital signature
_______________________________________________ OSGi Developer Mail List osgi-dev@mail.osgi.org https://mail.osgi.org/mailman/listinfo/osgi-dev