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

Reply via email to