Skip to content

Commit 2440f5e

Browse files
remove discovery, update notes
1 parent 4826701 commit 2440f5e

File tree

2 files changed

+14
-226
lines changed

2 files changed

+14
-226
lines changed

PR_NOTES.md

Lines changed: 14 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ The plugin system provides a higher-level abstraction over the existing intercep
1616

1717
**Decision:** `ClientPlugin` and `WorkerPlugin` each define their own `getName()` method independently, rather than sharing a base `Plugin` interface.
1818

19-
**Rationale:** This matches the Python SDK's design. Python has separate `ClientPlugin` and `WorkerPlugin` with `name()` on each. We initially had a base `Plugin` interface but removed it to simplify.
19+
**Rationale:** This matches the Python SDK's design. Python has separate `ClientPlugin` and `WorkerPlugin` with `name()` on each. I initially had a base `Plugin` interface but removed it to simplify.
20+
21+
**Alternative considered:** I could add a shared `Plugin` interface with just `getName()`. This would allow `List<Plugin>` instead of `List<?>` for storage. However, this adds an interface that serves no purpose other than type convenience, and Python doesn't have it.
2022

2123
### 2. `ClientPluginCallback` Interface (Module Boundary)
2224

@@ -26,33 +28,20 @@ The plugin system provides a higher-level abstraction over the existing intercep
2628
- `temporal-serviceclient` contains `WorkflowServiceStubs`
2729
- `temporal-sdk` depends on `temporal-serviceclient` (not vice versa)
2830
- `WorkflowServiceStubs.newServiceStubs(options, plugins)` needs to call plugin methods
29-
- Since serviceclient cannot import from sdk, we define a minimal callback interface in serviceclient
31+
- Since serviceclient cannot import from sdk, I define a minimal callback interface in serviceclient
3032

3133
This is the one structural difference from Python, which uses a single-package architecture where everything can import everything else.
3234

3335
### 3. `PluginBase` Convenience Class
3436

35-
**Decision:** Provide an abstract `PluginBase` class that implements both `ClientPlugin` and `WorkerPlugin`.
37+
**Decision:** I provide an abstract `PluginBase` class that implements both `ClientPlugin` and `WorkerPlugin`.
3638

37-
**Rationale:** Common Java pattern (like `AbstractList` for `List`). Reduces boilerplate for users writing custom plugins:
38-
```java
39-
// Without PluginBase
40-
public class MyPlugin implements ClientPlugin, WorkerPlugin {
41-
private final String name = "my-plugin";
42-
@Override public String getName() { return name; }
43-
// ... actual logic
44-
}
39+
**Rationale:** This is a common Java pattern (like `AbstractList` for `List`).
4540

46-
// With PluginBase
47-
public class MyPlugin extends PluginBase {
48-
public MyPlugin() { super("my-plugin"); }
49-
// ... actual logic (getName() inherited)
50-
}
51-
```
5241

5342
### 4. `SimplePluginBuilder` with Private `SimplePlugin`
5443

55-
**Decision:** Provide a builder for creating plugins declaratively, with the implementation class kept private.
44+
**Decision:** I provide a builder for creating plugins declaratively, with the implementation class kept private.
5645

5746
**Rationale:**
5847
- Builder pattern is more natural in Java than Python's constructor with many parameters
@@ -66,25 +55,18 @@ PluginBase myPlugin = SimplePluginBuilder.newBuilder("my-plugin")
6655
.build();
6756
```
6857

69-
### 5. `PluginDiscovery` - Optional ServiceLoader Discovery
58+
### 5. No ServiceLoader Discovery
7059

71-
**Decision:** Include a `PluginDiscovery` class that uses Java's `ServiceLoader` for auto-discovery.
60+
**Decision:** I do not include ServiceLoader-based plugin discovery.
7261

73-
**Status:** This is optional and currently **untested**. May be removed before merging.
74-
75-
**Rationale for including:** ServiceLoader is a standard Java pattern used by JDBC, logging frameworks, etc.
76-
77-
**Rationale for removing:**
62+
**Rationale:**
7863
- Python doesn't have this - just uses explicit `plugins=[]`
79-
- Adds complexity with questionable value
64+
- ServiceLoader requires classes with no-arg constructors, which doesn't integrate with `SimplePluginBuilder`
8065
- "Magic" discovery is harder to debug than explicit configuration
81-
- No test coverage
66+
- Explicit plugin configuration is clearer and sufficient
8267

83-
### 6. Plugin Storage Type
68+
We could consider adding it in though if there is interest.
8469

85-
**Decision:** `WorkflowClientOptions.getPlugins()` returns `List<?>` rather than a typed list.
86-
87-
**Rationale:** Without a common base interface, we need to store plugins that could be `ClientPlugin`, `WorkerPlugin`, or both. Using `List<?>` (or `List<Object>` internally) allows this flexibility. Users cast to the appropriate interface when needed.
8870

8971
## Files Changed
9072

@@ -93,7 +75,6 @@ PluginBase myPlugin = SimplePluginBuilder.newBuilder("my-plugin")
9375
- `WorkerPlugin.java` - Worker-side plugin interface
9476
- `PluginBase.java` - Convenience base class implementing both
9577
- `SimplePluginBuilder.java` - Builder for declarative plugin creation
96-
- `PluginDiscovery.java` - Optional ServiceLoader discovery (may remove)
9778

9879
### Modified Files
9980
- `WorkflowServiceStubs.java` - Added `newServiceStubs(options, plugins)` and `ClientPluginCallback` interface
@@ -106,32 +87,6 @@ PluginBase myPlugin = SimplePluginBuilder.newBuilder("my-plugin")
10687
- `SimplePluginBuilderTest.java` - Builder API tests
10788
- `WorkflowClientOptionsPluginTest.java` - Options integration tests
10889

109-
## Plugin Lifecycle
110-
111-
### Configuration Phase (forward order)
112-
```
113-
Plugin A.configureServiceStubs() → Plugin B → Plugin C
114-
Plugin A.configureClient() → Plugin B → Plugin C
115-
Plugin A.configureWorkerFactory() → Plugin B → Plugin C
116-
Plugin A.configureWorker() → Plugin B → Plugin C
117-
```
118-
119-
### Execution Phase (reverse order for proper nesting)
120-
```
121-
Plugin A wraps (
122-
Plugin B wraps (
123-
Plugin C wraps (
124-
actual operation
125-
)
126-
)
127-
)
128-
```
129-
130-
### Shutdown Phase (forward order)
131-
```
132-
Plugin A.onWorkerFactoryShutdown() → Plugin B → Plugin C
133-
```
134-
13590
## Example Usage
13691

13792
### Custom Plugin
@@ -180,6 +135,4 @@ WorkerFactory factory = WorkerFactory.newInstance(client);
180135

181136
## Open Questions
182137

183-
1. **Remove `PluginDiscovery`?** - It's untested and adds complexity. Python's explicit approach works fine.
184-
185-
2. **Mark as `@Experimental`?** - All public APIs are marked `@Experimental` to allow iteration.
138+
1. **Mark as `@Experimental`?** - I've marked all public APIs as `@Experimental` to allow iteration. Is this appropriate?

temporal-sdk/src/main/java/io/temporal/common/plugin/PluginDiscovery.java

Lines changed: 0 additions & 165 deletions
This file was deleted.

0 commit comments

Comments
 (0)