Skip to content

Commit 4b6eac7

Browse files
committed
fix(server): expose event processor startup
1 parent e2d6011 commit 4b6eac7

3 files changed

Lines changed: 35 additions & 16 deletions

File tree

‎docs/content/dev/server.md‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,4 +247,36 @@ See [Backward Compatibility](compatibility) for multi-version modules, version r
247247
- **Quarkus** — Reference implementations are Quarkus-based (JSON-RPC, gRPC, REST)
248248
- **Jakarta EE** — [a2a-jakarta](https://github.com/wildfly-extras/a2a-jakarta) works with any Jakarta EE Web Profile runtime
249249

250+
### Manual Wiring
251+
252+
For example, when wiring the server components as Spring beans, expose the event processor as a bean and pass it to the request handler. The handler starts the processor when it is constructed, including when the processor was created manually:
253+
254+
```java
255+
@Configuration
256+
class A2AServerConfiguration {
257+
258+
@Bean
259+
MainEventBus mainEventBus() {
260+
return new MainEventBus();
261+
}
262+
263+
@Bean
264+
MainEventBusProcessor mainEventBusProcessor(MainEventBus mainEventBus, TaskStore taskStore,
265+
PushNotificationSender pushSender, QueueManager queueManager) {
266+
return new MainEventBusProcessor(mainEventBus, taskStore, pushSender, queueManager);
267+
}
268+
269+
@Bean
270+
RequestHandler requestHandler(AgentExecutor agentExecutor, TaskStore taskStore,
271+
QueueManager queueManager, PushNotificationConfigStore pushConfigStore,
272+
MainEventBusProcessor mainEventBusProcessor,
273+
@Qualifier("a2aInternal") Executor executor) {
274+
return new DefaultRequestHandler(agentExecutor, taskStore, queueManager, pushConfigStore,
275+
mainEventBusProcessor, executor, executor);
276+
}
277+
}
278+
```
279+
280+
This assumes the other method parameters are also registered as Spring beans. The same executor is passed for agent execution and event consumption, as in this example; applications can provide separate executors when needed.
281+
250282
See [CONTRIBUTING_INTEGRATIONS.md](https://github.com/a2aproject/a2a-java/blob/main/CONTRIBUTING_INTEGRATIONS.md) to submit your own integration.

‎server-common/src/main/java/org/a2aproject/sdk/server/events/MainEventBusProcessor.java‎

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ int pushNotificationChainCount() {
158158

159159
@SuppressWarnings("NullAway.Init")
160160
@PostConstruct
161-
synchronized void start() {
161+
public synchronized void start() {
162162
if (processorThread != null && processorThread.isAlive()) {
163163
LOGGER.debug("MainEventBusProcessor already started");
164164
return;
@@ -170,17 +170,6 @@ synchronized void start() {
170170
LOGGER.info("MainEventBusProcessor started");
171171
}
172172

173-
/**
174-
* Ensures the background processor thread has been started.
175-
* <p>
176-
* In CDI runtimes, this forces proxy resolution and {@link PostConstruct}. For manual
177-
* wiring, this starts the processor directly.
178-
* </p>
179-
*/
180-
public void ensureStarted() {
181-
start();
182-
}
183-
184173
@PreDestroy
185174
synchronized void stop() {
186175
LOGGER.info("MainEventBusProcessor stopping...");

‎server-common/src/main/java/org/a2aproject/sdk/server/events/MainEventBusProcessorInitializer.java‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,12 @@ public class MainEventBusProcessorInitializer {
2727

2828
/**
2929
* Observes ApplicationScoped initialization to force eager creation of MainEventBusProcessor.
30-
* The injection of MainEventBusProcessor in this bean triggers its creation, and calling
31-
* ensureStarted() forces the CDI proxy to be resolved, which ensures @PostConstruct has been
30+
* Calling start() forces the CDI proxy to be resolved, which ensures @PostConstruct has been
3231
* called and the background thread is running.
3332
*/
3433
void onStart(@Observes @Initialized(ApplicationScoped.class) Object event) {
3534
if (processor != null) {
36-
// Force proxy resolution to ensure @PostConstruct has been called
37-
processor.ensureStarted();
35+
processor.start();
3836
LOGGER.info("MainEventBusProcessor initialized and started");
3937
} else {
4038
LOGGER.error("MainEventBusProcessor is null - initialization failed!");

0 commit comments

Comments
 (0)