package org.redisson; import static com.jayway.awaitility.Awaitility.await; import static org.assertj.core.api.Assertions.assertThat; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedList; import java.util.NoSuchElementException; import java.util.Queue; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import org.junit.Assert; import org.junit.Test; import org.redisson.RedisRunner.RedisProcess; import org.redisson.api.RBlockingQueue; import org.redisson.api.RFuture; import org.redisson.api.RedissonClient; import org.redisson.config.Config; public class RedissonBlockingQueueTest extends BaseTest { @Test public void testPollWithBrokenConnection() throws IOException, InterruptedException, ExecutionException { RedisProcess runner = new RedisRunner() .nosave() .randomDir() .randomPort() .run(); Config config = new Config(); config.useSingleServer().setAddress(runner.getRedisServerAddressAndPort()); RedissonClient redisson = Redisson.create(config); final RBlockingQueue<Integer> queue1 = redisson.getBlockingQueue("queue:pollTimeout"); RFuture<Integer> f = queue1.pollAsync(5, TimeUnit.SECONDS); Assert.assertFalse(f.await(1, TimeUnit.SECONDS)); runner.stop(); long start = System.currentTimeMillis(); assertThat(f.get()).isNull(); assertThat(System.currentTimeMillis() - start).isGreaterThan(3800); redisson.shutdown(); } @Test(timeout = 3000) public void testShortPoll() throws InterruptedException { RBlockingQueue<Integer> queue = redisson.getBlockingQueue("queue:pollany"); queue.poll(500, TimeUnit.MILLISECONDS); queue.poll(10, TimeUnit.MICROSECONDS); } @Test public void testPollReattach() throws InterruptedException, IOException, ExecutionException, TimeoutException { RedisProcess runner = new RedisRunner() .nosave() .randomDir() .randomPort() .run(); Config config = new Config(); config.useSingleServer().setAddress(runner.getRedisServerAddressAndPort()); RedissonClient redisson = Redisson.create(config); final AtomicBoolean executed = new AtomicBoolean(); Thread t = new Thread() { public void run() { try { RBlockingQueue<Integer> queue1 = redisson.getBlockingQueue("queue:pollany"); long start = System.currentTimeMillis(); Integer res = queue1.poll(10, TimeUnit.SECONDS); assertThat(System.currentTimeMillis() - start).isGreaterThan(2000); assertThat(res).isEqualTo(123); executed.set(true); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }; }; t.start(); t.join(1000); runner.stop(); runner = new RedisRunner() .port(runner.getRedisServerPort()) .nosave() .randomDir() .run(); Thread.sleep(1000); RBlockingQueue<Integer> queue1 = redisson.getBlockingQueue("queue:pollany"); queue1.put(123); t.join(); await().atMost(5, TimeUnit.SECONDS).until(() -> assertThat(executed.get()).isTrue()); redisson.shutdown(); runner.stop(); } @Test public void testPollAsyncReattach() throws InterruptedException, IOException, ExecutionException, TimeoutException { RedisProcess runner = new RedisRunner() .nosave() .randomDir() .randomPort() .run(); Config config = new Config(); config.useSingleServer().setAddress(runner.getRedisServerAddressAndPort()); RedissonClient redisson = Redisson.create(config); RBlockingQueue<Integer> queue1 = redisson.getBlockingQueue("queue:pollany"); RFuture<Integer> f = queue1.pollAsync(10, TimeUnit.SECONDS); f.await(1, TimeUnit.SECONDS); runner.stop(); runner = new RedisRunner() .port(runner.getRedisServerPort()) .nosave() .randomDir() .run(); queue1.put(123); // check connection rotation for (int i = 0; i < 10; i++) { queue1.put(i); } assertThat(queue1.size()).isEqualTo(10); Integer result = f.get(1, TimeUnit.SECONDS); assertThat(result).isEqualTo(123); redisson.shutdown(); runner.stop(); } @Test public void testTakeReattach() throws InterruptedException, IOException, ExecutionException, TimeoutException { RedisProcess runner = new RedisRunner() .nosave() .randomDir() .randomPort() .run(); Config config = new Config(); config.useSingleServer().setAddress(runner.getRedisServerAddressAndPort()); RedissonClient redisson = Redisson.create(config); RBlockingQueue<Integer> queue1 = redisson.getBlockingQueue("testTakeReattach"); RFuture<Integer> f = queue1.takeAsync(); f.await(1, TimeUnit.SECONDS); runner.stop(); runner = new RedisRunner() .port(runner.getRedisServerPort()) .nosave() .randomDir() .run(); queue1.put(123); // check connection rotation for (int i = 0; i < 10; i++) { queue1.put(i); } assertThat(queue1.size()).isEqualTo(10); Integer result = f.get(1, TimeUnit.SECONDS); assertThat(result).isEqualTo(123); runner.stop(); redisson.shutdown(); } @Test public void testTakeAsyncCancel() { Config config = createConfig(); config.useSingleServer().setConnectionMinimumIdleSize(1).setConnectionPoolSize(1); RedissonClient redisson = Redisson.create(config); RBlockingQueue<Integer> queue1 = redisson.getBlockingQueue("testTakeAsyncCancel"); for (int i = 0; i < 10; i++) { RFuture<Integer> f = queue1.takeAsync(); f.cancel(true); } assertThat(queue1.add(1)).isTrue(); assertThat(queue1.add(2)).isTrue(); assertThat(queue1.size()).isEqualTo(2); redisson.shutdown(); } @Test public void testPollAsyncCancel() { Config config = createConfig(); config.useSingleServer().setConnectionMinimumIdleSize(1).setConnectionPoolSize(1); RedissonClient redisson = Redisson.create(config); RBlockingQueue<Integer> queue1 = redisson.getBlockingQueue("queue:pollany"); for (int i = 0; i < 10; i++) { RFuture<Integer> f = queue1.pollAsync(1, TimeUnit.SECONDS); f.cancel(true); } assertThat(queue1.add(1)).isTrue(); assertThat(queue1.add(2)).isTrue(); assertThat(queue1.size()).isEqualTo(2); redisson.shutdown(); } @Test public void testPollFromAny() throws InterruptedException { final RBlockingQueue<Integer> queue1 = redisson.getBlockingQueue("queue:pollany"); Executors.newSingleThreadScheduledExecutor().schedule(() -> { RBlockingQueue<Integer> queue2 = redisson.getBlockingQueue("queue:pollany1"); RBlockingQueue<Integer> queue3 = redisson.getBlockingQueue("queue:pollany2"); try { queue3.put(2); queue1.put(1); queue2.put(3); } catch (InterruptedException e) { Assert.fail(); } }, 3, TimeUnit.SECONDS); long s = System.currentTimeMillis(); int l = queue1.pollFromAny(4, TimeUnit.SECONDS, "queue:pollany1", "queue:pollany2"); Assert.assertEquals(2, l); Assert.assertTrue(System.currentTimeMillis() - s > 2000); } @Test public void testTake() throws InterruptedException { RBlockingQueue<Integer> queue1 = redisson.getBlockingQueue("queue:take"); Executors.newSingleThreadScheduledExecutor().schedule(() -> { RBlockingQueue<Integer> queue = redisson.getBlockingQueue("queue:take"); try { queue.put(3); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }, 10, TimeUnit.SECONDS); long s = System.currentTimeMillis(); int l = queue1.take(); Assert.assertEquals(3, l); Assert.assertTrue(System.currentTimeMillis() - s > 9000); } @Test public void testPoll() throws InterruptedException { RBlockingQueue<Integer> queue1 = redisson.getBlockingQueue("queue1"); queue1.put(1); Assert.assertEquals((Integer)1, queue1.poll(2, TimeUnit.SECONDS)); long s = System.currentTimeMillis(); Assert.assertNull(queue1.poll(5, TimeUnit.SECONDS)); Assert.assertTrue(System.currentTimeMillis() - s > 5000); } @Test public void testAwait() throws InterruptedException { RBlockingQueue<Integer> queue1 = redisson.getBlockingQueue("queue1"); queue1.put(1); Assert.assertEquals((Integer)1, queue1.poll(10, TimeUnit.SECONDS)); } @Test public void testPollLastAndOfferFirstTo() throws InterruptedException { final RBlockingQueue<Integer> queue1 = redisson.getBlockingQueue("{queue}1"); Executors.newSingleThreadScheduledExecutor().schedule(() -> { try { queue1.put(3); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }, 10, TimeUnit.SECONDS); RBlockingQueue<Integer> queue2 = redisson.getBlockingQueue("{queue}2"); queue2.put(4); queue2.put(5); queue2.put(6); queue1.pollLastAndOfferFirstTo(queue2.getName(), 10, TimeUnit.SECONDS); assertThat(queue2).containsExactly(3, 4, 5, 6); } @Test public void testAddOfferOrigin() { Queue<Integer> queue = new LinkedList<Integer>(); queue.add(1); queue.offer(2); queue.add(3); queue.offer(4); assertThat(queue).containsExactly(1, 2, 3, 4); Assert.assertEquals((Integer) 1, queue.poll()); assertThat(queue).containsExactly(2, 3, 4); Assert.assertEquals((Integer) 2, queue.element()); } @Test public void testAddOffer() { RBlockingQueue<Integer> queue = redisson.getBlockingQueue("blocking:queue"); queue.add(1); queue.offer(2); queue.add(3); queue.offer(4); assertThat(queue).containsExactly(1, 2, 3, 4); Assert.assertEquals((Integer) 1, queue.poll()); assertThat(queue).containsExactly(2, 3, 4); Assert.assertEquals((Integer) 2, queue.element()); } @Test public void testRemoveOrigin() { Queue<Integer> queue = new LinkedList<Integer>(); queue.add(1); queue.add(2); queue.add(3); queue.add(4); queue.remove(); queue.remove(); assertThat(queue).containsExactly(3, 4); queue.remove(); queue.remove(); Assert.assertTrue(queue.isEmpty()); } @Test public void testRemove() { RBlockingQueue<Integer> queue = redisson.getBlockingQueue("blocking:queue"); queue.add(1); queue.add(2); queue.add(3); queue.add(4); queue.remove(); queue.remove(); assertThat(queue).containsExactly(3, 4); queue.remove(); queue.remove(); Assert.assertTrue(queue.isEmpty()); } @Test(expected = NoSuchElementException.class) public void testRemoveEmpty() { RBlockingQueue<Integer> queue = redisson.getBlockingQueue("blocking:queue"); queue.remove(); } @Test public void testDrainTo() { RBlockingQueue<Integer> queue = redisson.getBlockingQueue("queue"); for (int i = 0 ; i < 100; i++) { queue.offer(i); } Assert.assertEquals(100, queue.size()); Set<Integer> batch = new HashSet<Integer>(); int count = queue.drainTo(batch, 10); Assert.assertEquals(10, count); Assert.assertEquals(10, batch.size()); Assert.assertEquals(90, queue.size()); queue.drainTo(batch, 10); queue.drainTo(batch, 20); queue.drainTo(batch, 60); Assert.assertEquals(0, queue.size()); } @Test public void testBlockingQueue() { RBlockingQueue<Integer> queue = redisson.getBlockingQueue("test_:blocking:queue:"); ExecutorService executor = Executors.newFixedThreadPool(10); final AtomicInteger counter = new AtomicInteger(); int total = 100; for (int i = 0; i < total; i++) { // runnable won't be executed in any particular order, and hence, int value as well. executor.submit(() -> { redisson.getQueue("test_:blocking:queue:").add(counter.incrementAndGet()); }); } int count = 0; while (count < total) { try { // blocking int item = queue.take(); assertThat(item > 0 && item <= total).isTrue(); } catch (InterruptedException exception) { Assert.fail(); } count++; } assertThat(counter.get()).isEqualTo(total); queue.delete(); } @Test public void testDrainToCollection() throws Exception { RBlockingQueue<Object> queue1 = redisson.getBlockingQueue("queue1"); queue1.put(1); queue1.put(2L); queue1.put("e"); ArrayList<Object> dst = new ArrayList<Object>(); queue1.drainTo(dst); assertThat(dst).containsExactly(1, 2L, "e"); Assert.assertEquals(0, queue1.size()); } @Test public void testDrainToCollectionLimited() throws Exception { RBlockingQueue<Object> queue1 = redisson.getBlockingQueue("queue1"); queue1.put(1); queue1.put(2L); queue1.put("e"); ArrayList<Object> dst = new ArrayList<Object>(); queue1.drainTo(dst, 2); assertThat(dst).containsExactly(1, 2L); Assert.assertEquals(1, queue1.size()); dst.clear(); queue1.drainTo(dst, 2); assertThat(dst).containsExactly("e"); } @Test public void testSingleCharAsKeyName() { String value = "Long Test Message;Long Test Message;Long Test Message;" + "Long Test Message;Long Test Message;Long Test Message;Long " + "Test Message;Long Test Message;Long Test Message;Long Test " + "Message;Long Test Message;Long Test Message;Long Test Messa" + "ge;Long Test Message;Long Test Message;Long Test Message;Lo" + "ng Test Message;Long Test Message;Long Test Message;Long Te" + "st Message;Long Test Message;Long Test Message;Long Test Me" + "ssage;Long Test Message;Long Test Message;Long Test Message" + ";Long Test Message;Long Test Message;Long Test Message;Long" + " Test Message;Long Test Message;Long Test Message;Long Test" + " Message;Long Test Message;Long Test Message;Long Test Mess" + "age;"; try { for (int i = 0; i < 10; i++) { System.out.println("Iteration: " + i); RBlockingQueue<String> q = redisson.<String>getBlockingQueue(String.valueOf(i)); q.add(value); System.out.println("Message added to [" + i + "]"); q.expire(1, TimeUnit.MINUTES); System.out.println("Expiry set to [" + i + "]"); String poll = q.poll(1, TimeUnit.SECONDS); System.out.println("Message polled from [" + i + "]" + poll); Assert.assertEquals(value, poll); } } catch (Exception e) { Assert.fail(e.getLocalizedMessage()); } } }