INT-3520: Add Reactor's PersistentQueue Support

JIRA: https://jira.spring.io/browse/INT-3520

INT-3520: Use `Condition` to wait items in the `Queue`

INT-3520: Reworking to the `Semaphore(0)`

* Implement 'artificial infinite wait'
* Add distributed test with infinite `receive()`

INT-3520: Correct usage of `Semaphore`

Minor Doc Polishing
This commit is contained in:
Artem Bilan
2014-09-22 13:09:37 +03:00
committed by Gary Russell
parent a3d8776b5c
commit 5f9b04949e
6 changed files with 215 additions and 22 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,15 +28,22 @@ import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.integration.selector.UnexpiredMessageSelector;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.GenericMessage;
import reactor.io.encoding.JavaSerializationCodec;
import reactor.queue.PersistentQueue;
import reactor.queue.spec.PersistentQueueSpec;
/**
* @author Mark Fisher
* @author Artem Bilan
*/
public class QueueChannelTests {
@@ -237,4 +244,113 @@ public class QueueChannelTests {
assertTrue(channel.send(new GenericMessage<String>("roomAvailable"), 0));
}
@Rule
public final TemporaryFolder tempFolder = new TemporaryFolder();
@Test
public void testReactorPersistentQueue() throws InterruptedException {
final AtomicBoolean messageReceived = new AtomicBoolean(false);
final CountDownLatch latch = new CountDownLatch(1);
PersistentQueue<Message<?>> queue = new PersistentQueueSpec<Message<?>>()
.codec(new JavaSerializationCodec<Message<?>>())
.basePath(this.tempFolder.getRoot().getAbsolutePath())
.get();
final QueueChannel channel = new QueueChannel(queue);
new Thread(new Runnable() {
public void run() {
Message<?> message = channel.receive();
if (message != null) {
messageReceived.set(true);
latch.countDown();
}
}
}).start();
assertFalse(messageReceived.get());
channel.send(new GenericMessage<String>("testing"));
latch.await(1000, TimeUnit.MILLISECONDS);
assertTrue(messageReceived.get());
final CountDownLatch latch1 = new CountDownLatch(2);
Thread thread = new Thread(new Runnable() {
public void run() {
while (true) {
Message<?> message = channel.receive(100);
if (message != null) {
latch1.countDown();
if (latch1.getCount() == 0) {
break;
}
}
}
}
});
thread.start();
Thread.sleep(200);
channel.send(new GenericMessage<String>("testing"));
channel.send(new GenericMessage<String>("testing"));
assertTrue(latch1.await(1000, TimeUnit.MILLISECONDS));
final AtomicBoolean receiveInterrupted = new AtomicBoolean(false);
final CountDownLatch latch2 = new CountDownLatch(1);
Thread t = new Thread(new Runnable() {
public void run() {
Message<?> message = channel.receive(10000);
receiveInterrupted.set(true);
assertTrue(message == null);
latch2.countDown();
}
});
t.start();
assertFalse(receiveInterrupted.get());
t.interrupt();
latch2.await();
assertTrue(receiveInterrupted.get());
receiveInterrupted.set(false);
final CountDownLatch latch3 = new CountDownLatch(1);
t = new Thread(new Runnable() {
public void run() {
Message<?> message = channel.receive();
receiveInterrupted.set(true);
assertTrue(message == null);
latch3.countDown();
}
});
t.start();
assertFalse(receiveInterrupted.get());
t.interrupt();
latch3.await();
assertTrue(receiveInterrupted.get());
GenericMessage<String> message1 = new GenericMessage<String>("test1");
GenericMessage<String> message2 = new GenericMessage<String>("test2");
assertTrue(channel.send(message1));
assertTrue(channel.send(message2));
List<Message<?>> clearedMessages = channel.clear();
assertNotNull(clearedMessages);
assertEquals(2, clearedMessages.size());
clearedMessages = channel.clear();
assertNotNull(clearedMessages);
assertEquals(0, clearedMessages.size());
// Test on artificial infinite wait
// channel.receive();
// Distributed scenario
final CountDownLatch latch4 = new CountDownLatch(1);
new Thread(new Runnable() {
public void run() {
Message<?> message = channel.receive();
if (message != null) {
latch4.countDown();
}
}
}).start();
queue.add(new GenericMessage<String>("foo"));
assertTrue(latch4.await(1000, TimeUnit.MILLISECONDS));
}
}