Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Running promises on specific threads #68

Open
elFarto opened this issue Nov 3, 2015 · 3 comments
Open

Running promises on specific threads #68

elFarto opened this issue Nov 3, 2015 · 3 comments
Assignees
Labels

Comments

@elFarto
Copy link

elFarto commented Nov 3, 2015

Hi

I was looking to start using promises to remove the callback hell I've accumulated in my application, but I need to be able to ensure that a promise is run in a specific thread pool.

I had thought that DefaultDeferredManager.when(Promise) would do just that, but in fact it does nothing.

I was thinking you'd need something like this:

   private static <D, F, P> Promise<D, F, P> schedule(Promise<D, F, P> promise, Executor exe)
   {
      ScheduledDeferredObject<D, F, P> mdo = new ScheduledDeferredObject<>(exe);
      promise.then((D d) -> mdo.resolve(d), (F f) -> mdo.reject(f), (P p) -> mdo.notify(p));
      return mdo;
   }

   private static class ScheduledDeferredObject<D, F, P> extends DeferredObject<D, F, P>
   {
      private final Executor executor;

      public ScheduledDeferredObject(Executor executor)
      {
         this.executor = executor;
      }

      @Override
      public Deferred<D, F, P> resolve(final D resolve)
      {
         executor.execute(() -> super.resolve(resolve));
         return this;
      }

      @Override
      public Deferred<D, F, P> reject(final F reject)
      {
         executor.execute(() -> super.reject(reject));
         return this;
      }

      @Override
      public Deferred<D, F, P> notify(final P progress)
      {
         executor.execute(() -> super.notify(progress));
         return this;
      }
   }

Regards
Stephen

@nwertzberger
Copy link

Wrapping resolutions with a resolver that calls resolve() on a dedicated thread (maybe pulled from an ExecutorService) could be a way to do this.

@saturnism saturnism self-assigned this Feb 27, 2016
@saturnism
Copy link
Member

Hiya,

The DefaultDeferredManager can take an ExecutorService, and you should be able to use that to execute a Callable or Runnable. Does that help?

https://github.com/jdeferred/jdeferred#deferred-manager

@elFarto
Copy link
Author

elFarto commented Feb 27, 2016

In theory it should, but it doesn't appear to work as expected. I would expect this to print 'got result' on a different thread to the one that prints 'resolving', but they execute on the same thread, and a stack trace shows both methods on the stack. The situation I would need to use this in would requires that I don't process the callbacks in the thread that's doing the resolving, I have another thread pool for that.

   public static void main(String[] args) throws Exception
   {
      ExecutorService executorService = Executors.newCachedThreadPool();
      DeferredManager dm = new DefaultDeferredManager(executorService);
      Promise<String, Exception, Void> p = createPromise();

      dm.when(p).done((String result) -> {
         System.out.println(Thread.currentThread().getName() + ": got result: " + result);
      });
   }

   public static Promise<String, Exception, Void> createPromise()
   {
      final DeferredObject<String, Exception, Void> p = new DeferredObject<>();

      new Thread(() -> {
         try
         {
            Thread.sleep(5000);
            System.out.println(Thread.currentThread().getName() + ": resolving");
            p.resolve("hello");
         }
         catch (Throwable t)
         {
         }
      }).start();

      return p.promise();
   }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants