Skip to content

RedisList.reversed() view polls and peeks at the wrong end and ignores the poll timeout #3458

Description

@CCCLL

ReversedRedisListView (returned by RedisList.reversed(), since 3.2) delegates the queue head methods to the tail of the view, and poll(long, TimeUnit) additionally drops its arguments:

public E peek() {
	return peekLast();
}

public E poll() {
	return pollLast();
}

public E poll(long timeout, TimeUnit unit) throws InterruptedException {
	return pollLast(0, TimeUnit.SECONDS);
}

Deque and BlockingDeque define these methods as equivalent to peekFirst(), pollFirst() and pollFirst(timeout, unit). element(), pop(), remove() and drainTo(…) build on them and are affected as well, while take(), pollFirst(), removeFirst() and getFirst() already use the head of the view:

RedisList<String> list = RedisList.create("list", template); // [1, 2, 3]
RedisList<String> reversed = list.reversed();                // [3, 2, 1]

reversed.peekFirst(); // 3
reversed.peek();      // 1, expected 3
reversed.poll();      // 1, expected 3

Because the timeout is replaced with 0, a timed poll on an empty list sends BLPOP key 0 and does not return after the given timeout:

RedisList.create("empty", template).reversed().poll(1, TimeUnit.SECONDS);
// Lettuce: QueryTimeoutException after the 60 seconds command timeout
// Jedis: blocks indefinitely
// expected: null after 1 second

Reproduced on main against Redis 8.6.2 with Lettuce and Jedis. 3.5.x, 4.0.x and 4.1.x contain the same code. I will submit a PR with a fix and tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions