4
4
import com .beowulfe .hap .impl .http .HomekitClientConnection ;
5
5
import com .beowulfe .hap .impl .http .HttpResponse ;
6
6
import com .beowulfe .hap .impl .json .EventController ;
7
+ import java .util .ArrayList ;
7
8
import java .util .Collections ;
8
9
import java .util .Iterator ;
9
10
import java .util .Set ;
@@ -20,6 +21,9 @@ public class SubscriptionManager {
20
21
new ConcurrentHashMap <>();
21
22
private final ConcurrentMap <HomekitClientConnection , Set <EventableCharacteristic >> reverse =
22
23
new ConcurrentHashMap <>();
24
+ private final ConcurrentMap <HomekitClientConnection , ArrayList <PendingNotification >>
25
+ pendingNotifications = new ConcurrentHashMap <>();
26
+ private int nestedBatches = 0 ;
23
27
24
28
public synchronized void addSubscription (
25
29
int aid ,
@@ -72,6 +76,7 @@ public synchronized void removeSubscription(
72
76
73
77
public synchronized void removeConnection (HomekitClientConnection connection ) {
74
78
Set <EventableCharacteristic > characteristics = reverse .remove (connection );
79
+ pendingNotifications .remove (connection );
75
80
if (characteristics != null ) {
76
81
for (EventableCharacteristic characteristic : characteristics ) {
77
82
Set <HomekitClientConnection > characteristicSubscriptions =
@@ -91,10 +96,42 @@ private <T> Set<T> newSet() {
91
96
return Collections .newSetFromMap (new ConcurrentHashMap <T , Boolean >());
92
97
}
93
98
94
- public void publish (int accessoryId , int iid , EventableCharacteristic changed ) {
99
+ public synchronized void batchUpdate () {
100
+ ++this .nestedBatches ;
101
+ }
102
+
103
+ public synchronized void completeUpdateBatch () {
104
+ if (--this .nestedBatches == 0 && !pendingNotifications .isEmpty ()) {
105
+ LOGGER .info ("Publishing batched changes" );
106
+ for (ConcurrentMap .Entry <HomekitClientConnection , ArrayList <PendingNotification >> entry :
107
+ pendingNotifications .entrySet ()) {
108
+ try {
109
+ HttpResponse message = new EventController ().getMessage (entry .getValue ());
110
+ entry .getKey ().outOfBand (message );
111
+ } catch (Exception e ) {
112
+ LOGGER .error ("Faled to create new event message" , e );
113
+ }
114
+ }
115
+ pendingNotifications .clear ();
116
+ }
117
+ }
118
+
119
+ public synchronized void publish (int accessoryId , int iid , EventableCharacteristic changed ) {
120
+ if (nestedBatches != 0 ) {
121
+ LOGGER .info ("Batching change for " + accessoryId );
122
+ PendingNotification notification = new PendingNotification (accessoryId , iid , changed );
123
+ for (HomekitClientConnection connection : subscriptions .get (changed )) {
124
+ if (!pendingNotifications .containsKey (connection )) {
125
+ pendingNotifications .put (connection , new ArrayList <PendingNotification >());
126
+ }
127
+ pendingNotifications .get (connection ).add (notification );
128
+ }
129
+ return ;
130
+ }
131
+
95
132
try {
96
133
HttpResponse message = new EventController ().getMessage (accessoryId , iid , changed );
97
- LOGGER .info ("Publishing changes for " + accessoryId );
134
+ LOGGER .info ("Publishing change for " + accessoryId );
98
135
for (HomekitClientConnection connection : subscriptions .get (changed )) {
99
136
connection .outOfBand (message );
100
137
}
0 commit comments