'automatically remove items of a list every few second in redis

I'm trying to see how many users used my bot in the last 5 minute.

I've got an idea to every time a user used my bot I add his/hers id into a redis list with a timer. (reset the timer if user is already in the list)

And every time I want to check how many users are using the bot, I get the length of the list.

But i have no idea how to do that. something like below code that expiers five minute later:

redis.setex('foo_var', 60 * 5, 'foo_value')

I've managed to add items to a list with :

redis.zadd('foo', {'item1': 0, 'item2': 1})

And get the length of the list like this (I don't know how to get full length of the list. (without using min and max)):

min = 0.0
max = 1000.0
redis.zcount('foo', min, max)

Right now the problem is how to expire items of a list on specific time.



Solution 1:[1]

Items within Lists, Sets, Hashes, and their ilk cannot be expired automatically by Redis. That said, it might be worth looking at Streams.

If you're not familiar, Streams are essentially a list of events with associated times and associated data. Think of it like a log file. The nice thing is you can add extra data to the event, like maybe the type of bot interaction.

So, just log an event every time the bot is used:

XADD bot_events * eventType login

The * here means to auto generate the ID of the event based on the server time. You can also provided one manually, but you almost never want to. An event ID is just a UNIX Epoch time in milliseconds and a sequence number separated by a dash like this: 1651232477183-0.

XADD can automatically trim the Stream for your time period so old record don't hang around. Do this by providing an event ID before which events will be deleted:

XADD bot_events MINID ~ 1651232477183-0 * eventType login

Note that ~ instructs Redis to trim Streams performantly. This means that it might not delete all the events. However, it will never delete more than you expect, only less. It can be replaced with = if you want exactness over performance.

Now that you have a Stream of events, you can then query that Stream for events over a specific time period, based on event IDs:

XRANGE bot_events 1651232477183-0 +

+ here, means until the end of the stream. The initial event ID could be replaces with - if you want all the stream events regardless of the time.

From here, you just count the number of results.

Note, all the examples here are presented as raw Redis commands, but it should be easy enough to translate them to Python.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Guy Royse