Skip to content

Commit bfce8cb

Browse files
committed
Synchronize access to the state registry
1 parent e5dfce6 commit bfce8cb

2 files changed

Lines changed: 22 additions & 20 deletions

File tree

src/main/java/at/sv/hue/HueScheduler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ void discoverSceneStates() {
642642
public void start() {
643643
ZonedDateTime now = currentTime.get();
644644
scheduleSolarDataInfoLog();
645-
stateRegistry.values().forEach(statesForId -> initialSchedule(statesForId, now));
645+
stateRegistry.forEach(statesForId -> initialSchedule(statesForId, now));
646646
scheduleApiCacheClear();
647647
}
648648

src/main/java/at/sv/hue/ScheduledStateRegistry.java

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.util.Map;
1515
import java.util.Objects;
1616
import java.util.Optional;
17+
import java.util.function.Consumer;
1718
import java.util.function.Supplier;
1819
import java.util.stream.Collectors;
1920
import java.util.stream.Stream;
@@ -30,17 +31,17 @@ public ScheduledStateRegistry(Supplier<ZonedDateTime> currentTime, HueApi api) {
3031
lightStates = new LinkedHashMap<>();
3132
}
3233

33-
public void addState(ScheduledState state) {
34+
public synchronized void addState(ScheduledState state) {
3435
lightStates.computeIfAbsent(state.getId(), _ -> new ArrayList<>()).add(state);
3536
state.setPreviousStateLookup(this::getPreviousState);
3637
state.setNextStateLookup(this::getNextStateAfter);
3738
}
3839

39-
public void remove(ScheduledState state) {
40+
public synchronized void remove(ScheduledState state) {
4041
lightStates.get(state.getId()).remove(state);
4142
}
4243

43-
public ScheduledStateSnapshot getPreviousState(ScheduledStateSnapshot currentStateSnapshot) {
44+
public synchronized ScheduledStateSnapshot getPreviousState(ScheduledStateSnapshot currentStateSnapshot) {
4445
return getDistinctPreviousStatesBefore(currentStateSnapshot).stream()
4546
.findFirst()
4647
.orElse(null);
@@ -66,7 +67,7 @@ private List<ScheduledStateSnapshot> getDistinctPreviousStatesBefore(ScheduledSt
6667
.collect(Collectors.toList());
6768
}
6869

69-
public ScheduledStateSnapshot getNextStateAfter(ScheduledStateSnapshot currentState, ZonedDateTime definedStart) {
70+
public synchronized ScheduledStateSnapshot getNextStateAfter(ScheduledStateSnapshot currentState, ZonedDateTime definedStart) {
7071
ZonedDateTime theDayAfter = definedStart.plusDays(1).truncatedTo(ChronoUnit.DAYS).withEarlierOffsetAtOverlap();
7172
return findStatesForId(currentState).stream()
7273
.flatMap(state -> Stream.of(state.getSnapshot(definedStart), state.getSnapshot(theDayAfter)))
@@ -76,11 +77,11 @@ public ScheduledStateSnapshot getNextStateAfter(ScheduledStateSnapshot currentSt
7677
.orElse(null);
7778
}
7879

79-
public ScheduledState getLastSeenState(ScheduledStateSnapshot state) {
80+
public synchronized ScheduledState getLastSeenState(ScheduledStateSnapshot state) {
8081
return getLastSeenState(state.getId());
8182
}
8283

83-
public ScheduledState getLastSeenState(String id) {
84+
public synchronized ScheduledState getLastSeenState(String id) {
8485
List<ScheduledState> lightStatesForId = findStatesForId(id);
8586
if (lightStatesForId == null) {
8687
return null;
@@ -91,7 +92,7 @@ public ScheduledState getLastSeenState(String id) {
9192
.orElse(null);
9293
}
9394

94-
public long countOverlappingGroupStatesWithMoreLights(ScheduledStateSnapshot state) {
95+
public synchronized long countOverlappingGroupStatesWithMoreLights(ScheduledStateSnapshot state) {
9596
List<String> groupLights = getGroupLights(state);
9697
return getAssignedGroupsSortedBySizeDesc(groupLights)
9798
.stream()
@@ -109,7 +110,7 @@ private List<String> getGroupLights(ScheduledStateSnapshot state) {
109110
}
110111
}
111112

112-
public List<GroupInfo> getAssignedGroups(ScheduledStateSnapshot state) {
113+
public synchronized List<GroupInfo> getAssignedGroups(ScheduledStateSnapshot state) {
113114
List<String> groupLights = getGroupLights(state);
114115
List<GroupInfo> assignedGroups = getAssignedGroupsSortedBySizeDesc(groupLights);
115116
List<GroupInfo> additionalAreas = api.getAdditionalAreas(groupLights);
@@ -137,7 +138,7 @@ private List<GroupInfo> getAssignedGroupsSortedBySizeDesc(List<String> lightIds)
137138
* @param groupLights the list of light IDs for which to retrieve the active PutCall objects
138139
* @return a list of active PutCall objects corresponding to the provided light IDs
139140
*/
140-
public List<PutCall> getPutCalls(List<String> groupLights) {
141+
public synchronized List<PutCall> getPutCalls(List<String> groupLights) {
141142
ZonedDateTime now = currentTime.get();
142143
Map<String, PutCall> putCalls = getActivePutCallsFromGroups(groupLights, now);
143144
findActivePutCalls(groupLights, now).stream()
@@ -223,27 +224,28 @@ private List<ScheduledState> findStatesForId(ScheduledStateSnapshot snapshot) {
223224
return findStatesForId(snapshot.getId());
224225
}
225226

226-
public List<ScheduledState> findStatesForId(String id) {
227-
return lightStates.get(id);
227+
public synchronized List<ScheduledState> findStatesForId(String id) {
228+
List<ScheduledState> states = lightStates.get(id);
229+
return states != null ? new ArrayList<>(states) : null;
228230
}
229231

230-
public Collection<List<ScheduledState>> values() {
231-
return lightStates.values();
232+
public synchronized void forEach(Consumer<List<ScheduledState>> consumer) {
233+
lightStates.values().forEach(consumer);
232234
}
233235

234-
public List<ScheduledState> findStatesWithSceneId(String sceneId) {
236+
public synchronized List<ScheduledState> findStatesWithSceneId(String sceneId) {
235237
return lightStates.values().stream()
236238
.flatMap(List::stream)
237239
.filter(ScheduledState::isSceneBased)
238240
.filter(state -> sceneId.equals(state.getSceneId()))
239241
.toList();
240242
}
241243

242-
public List<ScheduledStateSnapshot> findCurrentlyActiveStates() {
244+
public synchronized List<ScheduledStateSnapshot> findCurrentlyActiveStates() {
243245
ZonedDateTime now = currentTime.get();
244-
return values().stream()
245-
.map(lightStatesForId -> findActiveSnapshot(lightStatesForId, now))
246-
.flatMap(Optional::stream)
247-
.toList();
246+
return lightStates.values().stream()
247+
.map(lightStatesForId -> findActiveSnapshot(lightStatesForId, now))
248+
.flatMap(Optional::stream)
249+
.toList();
248250
}
249251
}

0 commit comments

Comments
 (0)