How can I set/reset/change the stream top item id in Redis? - redis

While I was doing some testing in a Redis stream, I added a value into it with a high ID.
XADD mystream 9999999999999999-1 field value
Now I've found that this is the stream's top item, and trying to add anything with an automatic ID gets me
9999999999999999-2
Trying to add a stream with any ID lower than this results in an error:
(error) ERR The ID specified in XADD is equal or smaller than the target stream top item
I can just reset the stream back to my previous save of it, though I'm curious if there's any way to undo this action otherwise or reset the stream top item ID.

Related

Is there a bounded variant of UnicastProcessor?

The UnicastProcessor requests Long.MAX_VALUE elements on subscription and there is no way to set this while creating the processor.
I want to limit the number of requested items (to say 1) and only request next item once the previous items have been replayed to the subscriber. Also, the processor should only keep 1 subscriber and disconnect on second subscription, just like UnicastProcessor.

Redis streams is returning an empty array

I created a new Redis steam using the following command.
XGROUP CREATE A mygroup $ MKSTREAM
I added the below mentioned data
xadd A * X 1
xadd A * X 2
xadd A * X 3
xadd A * X 4
I am reading the data using the following command.
XREADGROUP GROUP mygroup Alice COUNT 1 STREAMS A 0
Its returning an empty array
1) 1) "A"
2) (empty array)
I am using Redis version 6.2.1. Kindly help me to debug the error.
When you use XREADGROUP command to read message, you should specify > as ID, instead of 0.
Reference from the doc:
The special > ID, which means that the consumer want to receive only messages that were never delivered to any other consumer. It just means, give me new messages.
Any other ID, that is, 0 or any other valid ID or incomplete ID (just the millisecond time part), will have the effect of returning entries that are pending for the consumer sending the command with IDs greater than the one provided. So basically if the ID is not >, then the command will just let the client access its pending entries: messages delivered to it, but not yet acknowledged. Note that in this case, both BLOCK and NOACK are ignored.
If ID is not >, you can only read pending messages, however, in your case, there's no pending message, since you have not consume anything.

Use XREADGROUP to get the id specified

I'm wondering if there is a command or parameter with which I can get the message for the RecordId specified e.g.
XREADGROUP GROUP mygroup myconsumer COUNT 1 STREAMS mystream 12345-0
I want the message with the ID 12345-0, but it seems I get the first message after 12345-0.
I cannot use XRANGE since it doesn't update the deliveryCount and lastDeliveryTime and it doesn't seem to understand the concept of consumer groups.
I'm also aware of
XREADGROUP GROUP mygroup myconsumer STREAMS mystream 0
which gives me all pending messages, but this would update the deliveryCount for all messages and I don't want that.
Redis itself doesn't provide the function you ask for. So instead you might have to
use something like
XREADGROUP GROUP mygroup myconsumer COUNT 1 STREAMS mystream 12344-99999
instead of "12345-0"
The entry id returned by Redis Stream is in the format of millisecondsTime-sequenceNumber.
Since it's unlikely you insert 99999 items in one milisecond, you can be sure that you get the correct item.

Retrieve value from expired keys

I have a use case where I'm aggregating until a TTL hits 0 on the key/value in Redis. As far as I can tell in the documentation, retrieval or a background job triggers all expired keys to be deleted immediately.
Is there anyway I can 'halt' that deletion and retrieve the value at the time of expiry? Or something similar to that effect?
My last question contains some context to my use case: Redis - any way to trigger an event when a value is no longer being actively written to?
I believe I found an answer to my question. Every row would have a corresponding row with with the convention expiry:{key}.
uniqueEventHash: [value1, value2, value3] // no expiry
expiry:uniqueEventHash: {no value} // set TTL to 60
Now, whenever a new value for that uniqueEventHash arrives, I do two things. I append it onto the uniqueEventHash row with an append, and then I also subsequently reset the TTL on expiry:uniqueEventHash to 60.
When events for that uniqueEventHash stop arriving, the second expiry:expiry:uniqueEventHash is deleted and a notification is sent out to a subscriber to EXPIRY events. In the message is the key that expired, which in this case is expiry:uniqueEventHash.
I can then do the following:
// pseudo code
onExpiryEvent(message):
[type, key] = eventMessage.split(':');
aggregatedValue = await getByKey(key);
del(key);

code delivery in stream impact on another stream

If code is delivered to a stream will it have any impact on another stream which has the same component.
eg :
stream 1
Comp 1 - baseline 1
Stream 2
Comp 1- baseline 1
If a create a repo workpace out of stream 2 and make code changes and deliver to Stream 2 will the change be available in stream 1.
Are the components same or two different copies?
Are the components same or two different copies?
They are the same component.
But each stream only display the LATEST changesets delivered for that component.
That means delivering new change sets on Stream2 (and making a new baseline) has no effect on the same component on Stream1.