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