Hi Simon,

It sounds as though you’re making pretty heavy use of Promises, which is great 
to hear! I agree that an external method can be used to provide timeouts, but 
the fact that users (including me) have felt it necessary to create the method 
indicates that it should probably be part of the core API. In general we have 
tried to keep the Promise well-encapsulated, so adding timeout to the Promise 
interface felt most consistent.

In the application model that you describe you are correct that (as long as all 
your callbacks are non-blocking) the extra resource overhead associated with 
creating many executors/schedulers is wasteful. Any compliant Promise 
implementation will work for you, but there are definitely non-functional 
advantages to picking (or creating) a specific implementation.

At the moment the behaviour of the OSGi-provided implementation works well for 
you, as it creates no threads at all, however as of Promises 1.1 this is likely 
to no longer be the case. This leaves you with a decision point:

Stick with Promises 1.0 - if the new functionality is not needed in your system 
then it is not mandatory to upgrade.
Use/Embed a specific implementation that gives you sufficient control of the 
threading. If you couple to a specific implementation (e.g. Apache Aries) then 
you can supply the Executor/Scheduler when you instantiate the Promise
Write your own promise implementation to get the finest possible control of the 
Promise lifecycle
Upgrade to the standard Promises 1.1, accepting that there will be some threads 
created


As someone also uses Promises quite a lot in infrastructure services, I can 
wholeheartedly recommend embedding a specific implementation if it gives you 
the control that you need. OSGi is very good at handling “substitutable” 
packages, i.e. providers that also import the API. An example would be the 
Aries Async Service implementation - the Async Service repackages the Aries 
Promise implementation, but imports the Promise API. This means that whichever 
way round bundles resolve they share the API packages, but it still allows 
Aries Async to use the Aries Promise implementation, avoiding excessive thread 
creation. This is the mechanism by which Felix SCR can use promises and 
co-exist in the same runtime as another promises provider.

Regards,

Tim


> On 11 Oct 2016, at 12:31, Simon Chemouil <ecli...@mithrandir.net> wrote:
> 
> Hi Timothy,
> 
> Thanks for your answer. Comments inlined.
> 
> [snip]
>> occur if the provider of the promise is mis-coded, or simply if the
>> triggering event never occurs. Timing out is usually the right thing to
>> do in these situations, so adding a primitive for that to the Promise
>> was made a target for Promises 1.1.
> 
> I agree, however this method can also be external. We have this method
> in our code base, on a separate service:
> 
> <T> Promise<T> timeLimit(Promise<T> promise, long delay, TimeUnit unit)
> 
> So while I understand it is practical to have as a fluent method on the
> Promise interface, it's not strictly required as a primitive.
> 
>> Updating the Apache Aries Async project is on my TODO list, I should
>> have it done in the next couple of weeks.
> 
> Great!
> 
>> As per the Promises specification, the method must not block. The rest
>> is down to the implementation of the promise - it would be perfectly
>> valid (although wasteful) to create a Timer, or a
>> ScheduledExecutorService inside each Promise. My plan in Aries is to
>> share the ScheduledExecutor where possible (i.e. in chained promises, or
>> promises created by the Async Service)
> 
> That is what I supposed. My main gripe with this approach is that
> Executors are holding system resources (threads) and I prefer designs
> that encapsulate such resources in services with a well-defined
> lifecycle. The sharing design still relies on automatic garbage
> collection. When trying to limit the number of threads in the JVM, I
> often end up chasing classes that spawn some. I am very fond of
> future/promises and I have been using the OSGi API a lot, so I am not
> sure of I feel about that change.
> 
> 
>> Non-blocking behaviour is required by the specification, but the
>> threading that you describe is the behaviour of one implementation. The
>> Promises specification purposefully does not define which thread is used
>> to run the callback. Apache Aries *always* uses a separate thread to run
>> callbacks, even in 1.0. This threading model gives a much greater scope
>> for optimisation when using the Async Service or Remote Services.
> 
> I don't use Async Service (because my services are designed to be async,
> and all return Promises on methods that do side-effects), or the Remote
> service (for other reasons). So I don't really know which optimisations
> this allows, but I guess it has to do with protecting these services
> against blocking user code.
> 
> In my case, I have a work stealing executor pool (as a service) running
> all non-blocking code, and service to create custom pools for blocking
> code (mostly because of blocking system calls such as mmap() or blocking
> APIs such as JDBC).
> 
> In that setting, I believe spawning threads for callbacks is more
> costly. The callbacks are already running by design in the right
> non-blocking dispatcher, with the appropriate size, and little
> thread/stack allocation cost (because it's already up and running).
> 
> I decided to go with the Promise API partly in part because it was
> cleanly separate from threading. The "reference" Promise implementation
> runs callbacks in the resolving thread, so it's perfect in my situation.
> 
> However, the timeout/delay design prevents me from doing that, short of
> writing my own PromiseImpl implementation that either takes a Scheduler
> as a parameter (and maybe redefine Deferred as well!), or resort to do a
> service lookup for my scheduler when those methods are called (which I'd
> rather not).
> 
> Also, using a custom org.osgi.promise implementation is a bit convoluted
> (because of bundles such as Felix SCR already exporting a version, and
> because it forces to order bundle resolution), so I'd be happy to avoid
> doing so.
> 
> 
>> I hope this helps,
> 
> It does, a lot! You answered my question exactly. Please treat my
> comments above as feedback from a happy user :).
> 
> Thanks for the great work you do. Looking forward to playing PushStreams
> as well.
> 
> Simon
> _______________________________________________
> OSGi Developer Mail List
> osgi-dev@mail.osgi.org
> https://mail.osgi.org/mailman/listinfo/osgi-dev

_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to