-
Notifications
You must be signed in to change notification settings - Fork 187
Plugin Support for Java SDK #2761
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
base: master
Are you sure you want to change the base?
Conversation
temporal-sdk/src/main/java/io/temporal/common/plugin/ClientPlugin.java
Outdated
Show resolved
Hide resolved
temporal-sdk/src/main/java/io/temporal/client/ClientPlugin.java
Outdated
Show resolved
Hide resolved
temporal-sdk/src/main/java/io/temporal/client/ClientPlugin.java
Outdated
Show resolved
Hide resolved
temporal-serviceclient/src/main/java/io/temporal/serviceclient/WorkflowServiceStubs.java
Outdated
Show resolved
Hide resolved
temporal-serviceclient/src/main/java/io/temporal/serviceclient/WorkflowServiceStubs.java
Outdated
Show resolved
Hide resolved
temporal-serviceclient/src/main/java/io/temporal/serviceclient/WorkflowServiceStubs.java
Outdated
Show resolved
Hide resolved
temporal-sdk/src/main/java/io/temporal/common/SimplePluginBuilder.java
Outdated
Show resolved
Hide resolved
temporal-sdk/src/main/java/io/temporal/common/plugin/WorkerPlugin.java
Outdated
Show resolved
Hide resolved
temporal-sdk/src/main/java/io/temporal/common/plugin/WorkerPlugin.java
Outdated
Show resolved
Hide resolved
temporal-sdk/src/main/java/io/temporal/common/plugin/WorkerPlugin.java
Outdated
Show resolved
Hide resolved
temporal-sdk/src/main/java/io/temporal/client/ClientPlugin.java
Outdated
Show resolved
Hide resolved
temporal-sdk/src/main/java/io/temporal/common/plugin/WorkerPlugin.java
Outdated
Show resolved
Hide resolved
temporal-sdk/src/main/java/io/temporal/common/SimplePlugin.java
Outdated
Show resolved
Hide resolved
…tdownWorkerFactory to SimplePlugin.
…ient to WorkflowClientPlugin.configureWorkflowClient
7be817f to
19fb453
Compare
| // Apply plugin configuration phase (forward order), then validate | ||
| WorkflowClientOptions.Builder builder = WorkflowClientOptions.newBuilder(options); | ||
| builder.setPlugins(mergedPlugins); | ||
| applyClientPluginConfiguration(builder, mergedPlugins); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cretz One subtle thing here with plugin propagation is what the plugins see, for which plugins are set on the builder when plugin.configureWorkflowClient(builder) is called on the plugin.
In this Java implementation, the plugins will all see the mergedPlugins (propagated + explicit).
In Python, the plugins only see the plugins that are in the explicit config, and not the propagated ones:
plugins_from_client = cast(
list[Plugin],
[p for p in client.config()["plugins"] if isinstance(p, Plugin)],
)
for client_plugin in plugins_from_client:
if type(client_plugin) in [type(p) for p in plugins]:
warnings.warn(
f"The same plugin type {type(client_plugin)} is present from both client and worker. It may run twice and may not be the intended behavior."
)
plugins = plugins_from_client + list(plugins)
self._initial_config = config.copy()
self._plugins = plugins
for plugin in plugins:
config = plugin.configure_worker(config)(that code is for _worker.py, but point still stands).
Do you have an intuition for which is the correct behavior and why? I would think that the Java behavior is more natural.
|
@cretz I think i've addressed everything. Could you do a re-review of the code? |
Plugin System for Java Temporal SDK
What was changed
Added a plugin system for the Java Temporal SDK, modeled after the Python SDK's plugin architecture but adapted to Java idioms.
New Plugin Interfaces
WorkflowServiceStubsPlugin(temporal-serviceclient) - Configuration and connection lifecycle for service stubsWorkflowClientPlugin(temporal-sdk) - Configuration for workflow clientsScheduleClientPlugin(temporal-sdk) - Configuration for schedule clientsWorkerPlugin(temporal-sdk) - Configuration and lifecycle for worker factories and workersSimplePlugin
SimplePlugin(temporal-sdk) - Abstract convenience class implementing all plugin interfacesSimplePlugin.newBuilder("name").build()Modified Files
WorkflowServiceStubsOptions- AddedpluginsfieldWorkflowServiceStubs- Applies plugin configuration and connection lifecycleWorkflowClientOptions- AddedpluginsfieldWorkflowClientInternalImpl- Applies plugin configuration, propagates from service stubsScheduleClientOptions- AddedpluginsfieldScheduleClientImpl- Applies plugin configuration, propagates from service stubsWorkerFactoryOptions- AddedpluginsfieldWorkerFactory- Full plugin lifecycle (configuration, worker init, start/shutdown)Test Files
PluginTest.java- Tests subclassing pattern and lifecycle orderingSimplePluginBuilderTest.java- Tests builder API comprehensivelyPluginPropagationTest.java- Integration tests for plugin propagation chainWorkflowClientOptionsPluginTest.java- Tests options class plugin field handlingWhy?
The plugin system provides a higher-level abstraction over the existing interceptor infrastructure, enabling users to:
Checklist
Closes Plugin support #2626, tracked in Plugins to support controlling multiple configuration points at once features#652
How was this tested:
Any docs updates needed?
Design
Plugin Interfaces
Each level in the creation chain has its own plugin interface:
Plugins set at higher levels propagate down automatically. For example, a plugin set on
WorkflowServiceStubsOptionsthat also implementsWorkflowClientPluginwill have itsconfigureWorkflowClient()method called when creating aWorkflowClient.SimplePlugin
SimplePluginis an abstract class that implements all plugin interfaces with sensible defaults. It can be used two ways:Builder pattern for declarative configuration:
Subclassing for custom behavior:
Usage Example