Please excuse if I am misinterpreting your reply, but I think you are referring to the fact that ThreadLocals can only be accessed by the owning thread. This is thought to work in my example as AsyncTaskHook.wrapQueueTask() is executed on the same thread as AsyncTaskService.queueTask(), and thus has access to the ThreadLocals. The shown hook implementation is incomplete (forgot to add that to the example, sorry...) as there should really be a constructor on the wrapper Runnable that extracts and saves the ThreadLocal data and keeps it until run() is called. There is one thing I guess I can't get in this design; knowledge that my Hook has been registered. In a startup scenario where all three bundles have just started, and MyBundle.myMethod() executes, I can't be sure that AsyncTaskService has registered my Hook and thus started considering the contextual workaround? If I want to be sure about this, I guess I need to switch to explicit registration with AsyncTaskService (not whiteboard), and delay publishing my ContextualService until I know my Hook has been registered. Or are there ways to make this work with a whiteboard design? Thanks Mike BJ Hargrave wrote:
Conceptually yes. But in the specific example, the queueTask method impl would need to do the wrapping since it know what thread's threadlocals to use. -- BJ Hargrave Senior Technical Staff Member, IBM OSGi Fellow and CTO of the <http://www.osgi.org/> OSGi Alliance <mailto:[email protected]> [email protected] office: +1 386 848 1781 mobile: +1 386 848 3788 From: Mike Wilson <[email protected]> To: "'OSGi Developer Mail List'" <[email protected]> Date: 2014/06/05 08:25 Subject: Re: [osgi-dev] cooperation between optional bundles Sent by: [email protected] _____ So based on the first alternative I made up the below example as an illustration. Let's say I have two services in my system: ContextualService (stores data in ThreadLocal) AsyncTaskService (runs tasks in separate threads) that are used by one of my other bundles: MyBundle.myMethod() { contextualService.doStuff(); asyncTaskService.queueTask(new Runnable() { public void run() { contextualService.doMoreStuff(); // fails } }); } then the call to doMoreStuff() will fail as the ThreadLocal is not available in the async thread. To solve this, AsyncTaskService could offer a Hook interface that ContextualService implements: interface AsyncTaskHook { Runnable wrapQueueTask(Runnable r); } class ContextualServiceAsyncTaskHook implements AsyncTaskHook { public Runnable wrapQueueTask(Runnable r) { return new Runnable() { public void run() { <set up ThreadLocals> <invoke original runnable> <clear ThreadLocals> } }); } } registerService(new ContextualServiceAsyncTaskHook()); that AsyncTaskService discovers whiteboard-style and invokes on every call to its queueTask method. Does this example make sense? Thanks Mike ________________________________ On Tue, Jun 3, 2014 at 8:32 AM, Mike Wilson <[email protected]> wrote: I'm looking at the generic problem of one optional bundle wanting to affect the behaviour of another optional bundle's service, without hard-wiring these bundles too much to each other. Each bundle should be deployable by itself in a system, but when both are available they should be able to hook into each other to affect the outcome of calls made on them by other bundles. As I have control over source code myself the first alternative that comes to mind is the "cooperative" style where each bundle could provide a custom Hook interface that others may implement. When executing calls from other bundles these Hook implementations could then be consulted for modifying the result of the operation. This seems to be in the spirit of many parts of core OSGi. Or, I could skip on the cooperative style and rely on framework ServiceHooks and proxies, which seems to be more hackish but may have advantages? Or are there other, better, alternatives? Thanks Mike Wilson _______________________________________________ OSGi Developer Mail List [email protected] <https://mail.osgi.org/mailman/listinfo/osgi-dev> https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________ OSGi Developer Mail List [email protected] https://mail.osgi.org/mailman/listinfo/osgi-dev
