use of org.apache.pulsar.common.util.collections.ConcurrentLongPairSet in project incubator-pulsar by apache.
the class PersistentTopicE2ETest method testMessageReplay.
/**
* Verify: 1. Broker should not replay already acknowledged messages 2. Dispatcher should not stuck while
* dispatching new messages due to previous-replay of invalid/already-acked messages
*
* @throws Exception
*/
@Test
public void testMessageReplay() throws Exception {
final String topicName = "persistent://prop/use/ns-abc/topic2";
final String subName = "sub2";
Message<byte[]> msg;
int totalMessages = 10;
int replayIndex = totalMessages / 2;
Consumer<byte[]> consumer = pulsarClient.newConsumer().topic(topicName).subscriptionName(subName).subscriptionType(SubscriptionType.Shared).receiverQueueSize(1).subscribe();
Producer<byte[]> producer = pulsarClient.newProducer().topic(topicName).create();
PersistentTopic topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(topicName);
assertNotNull(topicRef);
PersistentSubscription subRef = topicRef.getSubscription(subName);
PersistentDispatcherMultipleConsumers dispatcher = (PersistentDispatcherMultipleConsumers) subRef.getDispatcher();
Field replayMap = PersistentDispatcherMultipleConsumers.class.getDeclaredField("messagesToReplay");
replayMap.setAccessible(true);
ConcurrentLongPairSet messagesToReplay = new ConcurrentLongPairSet(64, 1);
assertNotNull(subRef);
// (1) Produce messages
for (int i = 0; i < totalMessages; i++) {
String message = "my-message-" + i;
producer.send(message.getBytes());
}
MessageIdImpl firstAckedMsg = null;
// (2) Consume and ack messages except first message
for (int i = 0; i < totalMessages; i++) {
msg = consumer.receive();
consumer.acknowledge(msg);
MessageIdImpl msgId = (MessageIdImpl) msg.getMessageId();
if (i == 0) {
firstAckedMsg = msgId;
}
if (i < replayIndex) {
// (3) accumulate acked messages for replay
messagesToReplay.add(msgId.getLedgerId(), msgId.getEntryId());
}
}
// (4) redelivery : should redeliver only unacked messages
Thread.sleep(1000);
replayMap.set(dispatcher, messagesToReplay);
// (a) redelivery with all acked-message should clear messageReply bucket
dispatcher.redeliverUnacknowledgedMessages(dispatcher.getConsumers().get(0));
assertEquals(messagesToReplay.size(), 0);
// (b) fill messageReplyBucket with already acked entry again: and try to publish new msg and read it
messagesToReplay.add(firstAckedMsg.getLedgerId(), firstAckedMsg.getEntryId());
replayMap.set(dispatcher, messagesToReplay);
// send new message
final String testMsg = "testMsg";
producer.send(testMsg.getBytes());
// consumer should be able to receive only new message and not the
dispatcher.consumerFlow(dispatcher.getConsumers().get(0), 1);
msg = consumer.receive(1, TimeUnit.SECONDS);
assertNotNull(msg);
assertEquals(msg.getData(), testMsg.getBytes());
consumer.close();
producer.close();
}
use of org.apache.pulsar.common.util.collections.ConcurrentLongPairSet in project incubator-pulsar by apache.
the class ConcurrentLongPairSetTest method testEqualsObjects.
@Test
public void testEqualsObjects() {
ConcurrentLongPairSet set = new ConcurrentLongPairSet();
long t1 = 1;
long t2 = 2;
long t1_b = 1;
assertEquals(t1, t1_b);
assertFalse(t1 == t2);
assertFalse(t1_b == t2);
set.add(t1, t1);
assertTrue(set.contains(t1, t1));
assertTrue(set.contains(t1_b, t1_b));
assertFalse(set.contains(t2, t2));
assertTrue(set.remove(t1_b, t1_b));
assertFalse(set.contains(t1, t1));
assertFalse(set.contains(t1_b, t1_b));
}
use of org.apache.pulsar.common.util.collections.ConcurrentLongPairSet in project incubator-pulsar by apache.
the class ConcurrentLongPairSetTest method testIteration.
@Test
public void testIteration() {
ConcurrentLongPairSet set = new ConcurrentLongPairSet();
assertEquals(set.items(), Collections.emptyList());
set.add(0l, 0l);
assertTrue(set.items().iterator().next().equals(new LongPair(0l, 0l)));
set.remove(0l, 0l);
assertEquals(set.items(), Collections.emptyList());
set.add(0l, 0l);
set.add(1l, 1l);
set.add(2l, 2l);
List<LongPair> values = new ArrayList<>(set.items());
values.sort(null);
assertEquals(values, Lists.newArrayList(new LongPair(0, 0), new LongPair(1, 1), new LongPair(2, 2)));
set.clear();
assertTrue(set.isEmpty());
}
use of org.apache.pulsar.common.util.collections.ConcurrentLongPairSet in project incubator-pulsar by apache.
the class ConcurrentLongPairSetTest method testRemoval.
@Test
public void testRemoval() {
ConcurrentLongPairSet set = new ConcurrentLongPairSet();
set.add(0, 0);
set.add(1, 1);
set.add(3, 3);
set.add(6, 6);
set.add(7, 7);
List<LongPair> values = new ArrayList<>(set.items());
values.sort(null);
assertEquals(values, Lists.newArrayList(new LongPair(0, 0), new LongPair(1, 1), new LongPair(3, 3), new LongPair(6, 6), new LongPair(7, 7)));
set.forEach((first, second) -> {
if (first < 5) {
set.remove(first, second);
}
});
assertEquals(set.size(), values.size() - 3);
values = new ArrayList<>(set.items());
values.sort(null);
assertEquals(values, Lists.newArrayList(new LongPair(6, 6), new LongPair(7, 7)));
}
use of org.apache.pulsar.common.util.collections.ConcurrentLongPairSet in project incubator-pulsar by apache.
the class ConcurrentLongPairSetTest method testRehashingRemoval.
@Test
public void testRehashingRemoval() {
int n = 16;
ConcurrentLongPairSet set = new ConcurrentLongPairSet(n / 2, 1);
assertEquals(set.capacity(), n);
assertEquals(set.size(), 0);
int insertItems = 1000 * n;
for (int i = 0; i < insertItems; i++) {
set.add(i, -1);
}
int newSize = (int) Math.pow(2, 32 - Integer.numberOfLeadingZeros(insertItems - 1));
assertEquals(set.capacity(), newSize * 2);
assertEquals(set.size(), insertItems);
Set<LongPair> pairs = new HashSet<>();
set.forEach((first, second) -> {
pairs.add(new LongPair(first, second));
});
pairs.forEach(pair -> set.remove(pair.first, -1));
assertEquals(set.capacity(), newSize * 2);
assertEquals(set.size(), 0);
}
Aggregations