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

Async APIs #269

Open
bsideup opened this issue Jan 2, 2019 · 10 comments

Comments

@bsideup
Copy link

@bsideup bsideup commented Jan 2, 2019

Hi!

Would you consider supporting Async APIs?

There are some IO blocking operations (e.g. loading of plugins, or even plugin's startup), and currently, in my async non-blocking app, I have to run them in a special thread pool (although the implementations of the plugin repository and plugins themselves are async)

CompletionStage<Void> could be used in place of potentially-IO methods with void type, and CompletionStage<T> where it returns something.

Consider this issue as a feature request & design discussion for now :)

@decebals

This comment has been minimized.

Copy link
Member

@decebals decebals commented Jan 2, 2019

Thanks for idea!

Another interesting idea is to load plugins in parallel (if a plugin is not a dependency for another plugin we can load them in parallel) to decrease the startup time of application. But I consider these kind of features somehow enterprise.

I am curios to see how we can implement this feature in a clean and non intrusive way. Any draft, snippet code, idea that will move forward this feature or a concrete PR is welcome.

@decebals

This comment has been minimized.

Copy link
Member

@decebals decebals commented Jan 2, 2019

And to not forget, to use CompetionStage we need to migrate PF4J from Java 7 to Java 8. I think that this migration will not be a problem because Java 8 is already old.

@bsideup

This comment has been minimized.

Copy link
Author

@bsideup bsideup commented Jan 2, 2019

@decebals I'll sketch something. The bigger challenge is how to keep it backward compatible. Otherwise, it has to be targeted for 3.x, I guess

@decebals

This comment has been minimized.

Copy link
Member

@decebals decebals commented Jan 2, 2019

@bsideup

The bigger challenge is how to keep it backward compatible. Otherwise, it has to be targeted for 3.x, I guess

3.x is perfect. For 3.x we will increase the minimal Java version to 8.

@decebals

This comment has been minimized.

Copy link
Member

@decebals decebals commented Jan 2, 2019

I am thinking if it's not possible to add new default async methods in PluginManager for example, methods that transform the existed sync peer methods in async methods using a decorator (as pattern).
If async methods are declared as default methods we don't break the existent API.

@decebals decebals added the enhancement label Jan 7, 2019
@decebals decebals mentioned this issue Feb 26, 2019
2 of 3 tasks complete
@decebals decebals added this to the PF4J 3 milestone Mar 26, 2019
@decebals

This comment has been minimized.

Copy link
Member

@decebals decebals commented Mar 26, 2019

@bsideup
We started work on PF4J 3. The modifications are available on pf4j_3 branch.
With your help, this issue can be available in PF4J 3. It is already added for this milestone.

@decebals

This comment has been minimized.

Copy link
Member

@decebals decebals commented Apr 15, 2019

This feature will be removed from PF4J 3 milestone, because the interest for this feature is low.
It can delay the release of PF4J 3 that is almost ready.

@decebals decebals removed this from the PF4J 3 milestone Apr 15, 2019
@decebals

This comment has been minimized.

Copy link
Member

@decebals decebals commented Apr 18, 2019

I added a POC (Proof Of Concept) on the async branch.
I updated demo (Boot class) to use the new Async API. Everything is functional.
I am not an expert of async/reactive/... so I don't contest that are not mistakes or that it cannot be improved it :)
Any advice, PR is very welcome.

@decebals

This comment has been minimized.

Copy link
Member

@decebals decebals commented Apr 19, 2019

I added below two code snippets (from demo/Boot.java) that show you the API used to load&start plugins using SYNC and ASYNC variant.
In the new async API I added two new methods (until now) that end with Async:

  • loadPluginsAsync
  • startPluginsAsync

Load and start plugins sync

// create the plugin manager
final PluginManager pluginManager = new DefaultPluginManager();

// load the plugins
pluginManager.loadPlugins();

// start (active/resolved) the plugins
pluginManager.startPlugins();

// retrieves the extensions for Greeting extension point
List<Greeting> greetings = pluginManager.getExtensions(Greeting.class);

Load and start plugins async

// create the plugin manager
final AsyncPluginManager pluginManager = new DefaultAsyncPluginManager();

// load the plugins
CompletionStage<Void> stage = pluginManager.loadPluginsAsync();
stage.thenRun(() -> System.out.println("Plugins loaded")); // optional

// start (active/resolved) the plugins
stage.thenCompose(v -> pluginManager.startPluginsAsync());
stage.thenRun(() -> System.out.println("Plugins started")); // optional

// block and wait for the future to complete (not the best approach in real applications)
stage.toCompletableFuture().get();

// retrieves the extensions for Greeting extension point
List<Greeting> greetings = pluginManager.getExtensions(Greeting.class);

I am not sure yet if the variant with new AsyncPluginManager interface and DefaultAsyncPluginManager class is the best design option. I don't know if the variant with add the new async methods directly in PluginManager is not better.

@decebals

This comment has been minimized.

Copy link
Member

@decebals decebals commented Apr 24, 2019

To the solution proposed by me can be added support for timeout via CompletableFeature.orTimeout (Java 9+) or a similar method using ScheduledThreadPoolExecutor (Java 8).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.