1
1
package org .tinystruct .http ;
2
2
3
+ import org .tinystruct .data .component .Builder ;
4
+
3
5
import java .util .Set ;
4
6
import java .util .concurrent .ConcurrentHashMap ;
5
7
import java .util .concurrent .ExecutorService ;
6
8
import java .util .concurrent .Executors ;
9
+ import java .util .concurrent .atomic .AtomicBoolean ;
10
+ import java .util .concurrent .BlockingQueue ;
11
+ import java .util .logging .Level ;
12
+ import java .util .logging .Logger ;
7
13
8
14
public class SSEPushManager {
15
+ private static final Logger logger = Logger .getLogger (SSEPushManager .class .getName ());
9
16
private final ConcurrentHashMap <String , SSEClient > clients = new ConcurrentHashMap <>();
10
17
private final ExecutorService executor = Executors .newCachedThreadPool ();
18
+ private final AtomicBoolean isShutdown = new AtomicBoolean (false );
11
19
12
20
private static final SSEPushManager instance = new SSEPushManager ();
13
21
@@ -18,24 +26,59 @@ public static SSEPushManager getInstance() {
18
26
}
19
27
20
28
public void register (String sessionId , Response out ) {
21
- SSEClient client = new SSEClient (out );
29
+ register (sessionId , out , null );
30
+ }
31
+
32
+ public void register (String sessionId , Response out , BlockingQueue <Builder > messageQueue ) {
33
+ if (isShutdown .get ()) {
34
+ logger .log (Level .WARNING , "SSEPushManager is shutting down, cannot register new client" );
35
+ return ;
36
+ }
37
+
38
+ SSEClient oldClient = clients .get (sessionId );
39
+ if (oldClient != null ) {
40
+ oldClient .close ();
41
+ }
42
+
43
+ SSEClient client = messageQueue != null ?
44
+ new SSEClient (out , messageQueue ) :
45
+ new SSEClient (out );
46
+
22
47
clients .put (sessionId , client );
23
48
executor .submit (client );
24
49
}
25
50
26
- public void push (String sessionId , String message ) {
51
+ public void push (String sessionId , Builder message ) {
52
+ if (isShutdown .get ()) {
53
+ logger .log (Level .WARNING , "SSEPushManager is shutting down, cannot push message" );
54
+ return ;
55
+ }
56
+
27
57
SSEClient client = clients .get (sessionId );
28
- if (client != null && client .isActive ()) {
29
- client .send (message );
58
+ if (client != null ) {
59
+ if (client .isActive ()) {
60
+ client .send (message );
61
+ } else {
62
+ // Clean up inactive client
63
+ clients .remove (sessionId , client );
64
+ }
30
65
}
31
66
}
32
67
33
- public void broadcast (String message ) {
34
- for (SSEClient client : clients .values ()) {
68
+ public void broadcast (Builder message ) {
69
+ if (isShutdown .get ()) {
70
+ logger .log (Level .WARNING , "SSEPushManager is shutting down, cannot broadcast message" );
71
+ return ;
72
+ }
73
+
74
+ clients .forEach ((sessionId , client ) -> {
35
75
if (client .isActive ()) {
36
76
client .send (message );
77
+ } else {
78
+ // Clean up inactive client
79
+ clients .remove (sessionId , client );
37
80
}
38
- }
81
+ });
39
82
}
40
83
41
84
public void remove (String sessionId ) {
@@ -48,4 +91,15 @@ public void remove(String sessionId) {
48
91
public Set <String > getClientIds () {
49
92
return clients .keySet ();
50
93
}
94
+
95
+ public void shutdown () {
96
+ if (isShutdown .compareAndSet (false , true )) {
97
+ // Close all clients
98
+ clients .forEach ((sessionId , client ) -> client .close ());
99
+ clients .clear ();
100
+
101
+ // Shutdown executor
102
+ executor .shutdown ();
103
+ }
104
+ }
51
105
}
0 commit comments