LifecycleEventManager.java
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------------------------------------------*/
package com.github.copilot.sdk;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.github.copilot.sdk.json.SessionLifecycleEvent;
import com.github.copilot.sdk.json.SessionLifecycleHandler;
/**
* Manages lifecycle event subscriptions and dispatching.
* <p>
* This class handles registration/unregistration of lifecycle event handlers
* and dispatches events to the appropriate handlers.
*/
final class LifecycleEventManager {
private static final Logger LOG = Logger.getLogger(LifecycleEventManager.class.getName());
private final List<SessionLifecycleHandler> wildcardHandlers = new ArrayList<>();
private final Map<String, List<SessionLifecycleHandler>> typedHandlers = new ConcurrentHashMap<>();
private final Object handlersLock = new Object();
/**
* Subscribes to all session lifecycle events.
*
* @param handler
* a callback that receives lifecycle events
* @return an AutoCloseable that, when closed, unsubscribes the handler
*/
AutoCloseable subscribe(SessionLifecycleHandler handler) {
synchronized (handlersLock) {
wildcardHandlers.add(handler);
}
return () -> {
synchronized (handlersLock) {
wildcardHandlers.remove(handler);
}
};
}
/**
* Subscribes to a specific session lifecycle event type.
*
* @param eventType
* the event type to listen for
* @param handler
* a callback that receives events of the specified type
* @return an AutoCloseable that, when closed, unsubscribes the handler
*/
AutoCloseable subscribe(String eventType, SessionLifecycleHandler handler) {
synchronized (handlersLock) {
typedHandlers.computeIfAbsent(eventType, k -> new ArrayList<>()).add(handler);
}
return () -> {
synchronized (handlersLock) {
List<SessionLifecycleHandler> handlers = typedHandlers.get(eventType);
if (handlers != null) {
handlers.remove(handler);
}
}
};
}
/**
* Dispatches a lifecycle event to all registered handlers.
*
* @param event
* the lifecycle event to dispatch
*/
void dispatch(SessionLifecycleEvent event) {
List<SessionLifecycleHandler> typed;
List<SessionLifecycleHandler> wildcard;
synchronized (handlersLock) {
List<SessionLifecycleHandler> handlers = typedHandlers.get(event.getType());
typed = handlers != null ? new ArrayList<>(handlers) : new ArrayList<>();
wildcard = new ArrayList<>(wildcardHandlers);
}
for (SessionLifecycleHandler handler : typed) {
try {
handler.onLifecycleEvent(event);
} catch (Exception e) {
LOG.log(Level.WARNING, "Lifecycle handler error", e);
}
}
for (SessionLifecycleHandler handler : wildcard) {
try {
handler.onLifecycleEvent(event);
} catch (Exception e) {
LOG.log(Level.WARNING, "Lifecycle handler error", e);
}
}
}
}