Skip to content

Commit

Permalink
Fix ready marker ordering on late subscriptions (#3454)
Browse files Browse the repository at this point in the history
Signed-off-by: Jan N. Klug <[email protected]>
  • Loading branch information
J-N-K authored Mar 13, 2023
1 parent 73b8a3a commit c05fe8a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@

import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer;

Expand All @@ -38,7 +38,7 @@ public class ReadyServiceImpl implements ReadyService {
private final Logger logger = LoggerFactory.getLogger(ReadyServiceImpl.class);
private static final ReadyMarkerFilter ANY = new ReadyMarkerFilter();

private final Set<ReadyMarker> markers = Collections.newSetFromMap(new ConcurrentHashMap<>());
private final Set<ReadyMarker> markers = Collections.synchronizedSet(new LinkedHashSet<>());

private final Map<ReadyTracker, ReadyMarkerFilter> trackers = new HashMap<>();
private final ReentrantReadWriteLock rwlTrackers = new ReentrantReadWriteLock(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@
*/
package org.openhab.core.internal.service;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.*;

import java.util.List;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.openhab.core.service.ReadyMarker;
import org.openhab.core.service.ReadyMarkerFilter;
import org.openhab.core.service.ReadyService.ReadyTracker;
Expand Down Expand Up @@ -84,4 +89,17 @@ public void testUnregisterTracker() {
verify(tracker).onReadyMarkerRemoved(isA(ReadyMarker.class));
verifyNoMoreInteractions(tracker);
}

@Test
public void testReadyMarkerOrderPreserved() {
ReadyTracker tracker = mock(ReadyTracker.class);
ReadyServiceImpl rs = new ReadyServiceImpl();
List<ReadyMarker> markers = List.of(new ReadyMarker("foo", "c"), new ReadyMarker("foo", "1"),
new ReadyMarker("foo", "a"), new ReadyMarker("foo", "3"));
markers.forEach(rs::markReady);
rs.registerTracker(tracker, new ReadyMarkerFilter().withType("foo"));
ArgumentCaptor<ReadyMarker> captor = ArgumentCaptor.forClass(ReadyMarker.class);
verify(tracker, times(4)).onReadyMarkerAdded(captor.capture());
assertThat(captor.getAllValues(), Matchers.contains(markers.toArray(ReadyMarker[]::new)));
}
}

0 comments on commit c05fe8a

Please sign in to comment.