Redis subscriber is not notified by EXPIRE key 0 - events

I've got a Redis client subscribed to __keyevent#0__:expired notifications. It works perfectly, either when the key expires by itself (ttl reached) or when I expire them manually with a number of seconds greater than 0, like so:
EXPIRE myKey 1
The subscriber sees the expired event and can therefore take some actions.
However, if I want to manually delete the key and have the subscriber notified, I use EXPIRE with 0 as the number of seconds:
EXPIRE myKey 0
The key gets deleted, but the subscriber doesn't receive anything.
I can't see anything related to this in the doc. Can anyone explain this behavior?

From reviewing the source code (expire.c, ~252), setting an expiry value of <=0 (or using EXPIREAT with a time in the past) results in a deletion of the key rather than an expiry (and accordingly a DEL notification rather than an EXPIRED event).
This behavior is indeed undocumented and it would be good if you could submit a PR that fixes that to the documentation repo (https://github.com/antirez/redis-doc).

Related

How to choose the right value for the expiryTime parameter for RedLockFactory.CreateLockAsync() method?

I am using RedLock.net library for resource locking. To lock a resoruce I am using RedLockFactory.CreateLockAsync.
public async Task<IRedLock> RedLockFactory.CreateLockAsync(string resource,
TimeSpan expiryTime,
TimeSpan waitTime,
TimeSpan retryTime,
CancellationToken? cancellationToken = null)
I understand that this method will attempt to acquire a lock for waitTime by keep retrying every retryTime. However I do not understand what would be the right value for expiryTime.
Once a lock has been acquired it will be kept until the lock is Disposed and that is irrespective of the expiryTime. In other words even if expirtyTime is set to 5 seconds if the lock is only diposed after 10 seconds then the lock will be kept for 10 seconds.
In many examples the value of 30 is used without explanation.
I have tested with a value of 0. A lock is not acquired at all.
I have tested with a value of 5 milliseconds. A lock is acquired and kept until disposed.
So how to choose the right value for the expiryTime parameter? It seems to me that this parameter is unnecessary and any non zero positive value is ok.
ExpiryTime determines the maximum time that a lock will be held in the case of a failure (say, the process holding the lock crashing). It also indirectly determines how often the lock is renewed while it is being held.
e.g.
If you set an expiry time of 10 minutes:
the automatic lock renewal timer will call out to redis every 5 minutes (expiry time / 2) to extend the lock
if your process crashes without releasing the lock, you will have to wait up to a maximum of 10 minutes until the key expires in redis and another process can take out a lock on the same resource
If you set an expiry time of 10 milliseconds:
the automatic lock renewal timer will call out to redis every 5 milliseconds (expiry time / 2) to extend the lock (which might be a little excessive)
if your process crashes without releasing the lock, you will have to wait up to a maximum of 10 milliseconds until the key expires in redis and another process can take out a lock on the same resource
It's a balance between how much time you're willing to wait for a lock to expire in the failure case vs how much load you put on your redis servers.

Understanding Laravel Session Handler

I am trying to understand Laravels session handler and can't find anything online. At the moment, in session.php I am doing
'lifetime' => 10,
I have the session driver set to file. So from what I have read, this sets the idle timeout of the session to 10 minutes.
So what does idle mean in this case? I am assuming it means if no request is sent to the server within 10 minutes it will expire. Is this correct?
Also, how can it tell if no request has been sent within 10 minutes? I have taken a look at the session file within storage, and I do not see any timestamp.
So how exactly does all of this work?
Thanks
Yes you are correct: if you don't send any request after the lifetime config value the session will be destroyed.
The Illuminate\Session\FileSessionHandler class has a gc() function, it is a garbage collector function that has a probability to be called on every request, you can control the chances with the session.lottery config value. This function destroy each session file that has a modified timestamp older than now - lifetime.
You can find the Illuminate\Session\FileSessionHandler class in the file vendor/laravel/framework/src/Illuminate/Session/FileSessionHandler.php if you want to take a look at the source code.

FB Messenger API - Receiving double requests

I have a working FB Bot built with Ruby which allows players to play a scavenger hunt.
Sometimes though, when I have multiple players in a team, FB is sending me a players 'Answer' webhook twice. I have looked into it and at first thought it was to do with the 20 second timeout if FB gets no 200 OK response (Docs here). After checking the logs though, I am receiving the second webhook from FB only 14 seconds later. See below:
# Webhook #1
{"object"=>"page", "entry"=>[{"id"=>"252445748474312", "time"=>1532153642358, "messaging"=>[{"sender"=>{"id"=>"1709242109154907"}, "recipient"=>{"id"=>"252445748474312"}, "timestamp"=>1532153641935, "message"=>{"mid"=>"0FeOChulGjuPgg3YJqEgajNsY8kMfNRt_bpIdeegEeE54h-KB8szcd-EQ-UHUT3850RwHgH4TxVYFkoFwxqhtg", "seq"=>402953, "text"=>"Larrikins"}}]}]}
# Webhook #2 (14 seconds later)
{"object"=>"page", "entry"=>[{"id"=>"252445748474312", "time"=>1532153656901, "messaging"=>[{"sender"=>{"id"=>"1709242109154907"}, "recipient"=>{"id"=>"252445748474312"}, "timestamp"=>1532153641935, "message"=>{"mid"=>"0FeOChulGjuPgg3YJqEgajNsY8kMfNRt_bpIdeegEeE54h-KB8szcd-EQ-UHUT3850RwHgH4TxVYFkoFwxqhtg", "seq"=>402953, "text"=>"Larrikins"}}]}]}
Notice both are exactly the same apart from the first "time" attribute (14 secs later).
Due to a number of methods and calls that I process after receiving the first webhook, the 200 OK response is only being sent back to FB once I have finished sending my messages in response (hence the 14 second delay).
So I have two questions:
Is the 14 second delay too long and that is why FB is resending? If so, how can I send a 200OK response straight away (head :ok)?
Is it another issue entirely?
You also ensure that "Echo" is disabled.
Go to Settings>Webhooks, edit events.
Asyncronous language like NodeJS is recomended, in my case y work with AWS SQS, I have workers that process the requests witout blocking (dont wait), I return 200,"ok" to FB to avoid that FB send again the message to my webhook.
Anothe apporach maybe store the mid in database, and check in each request if the mid exists, if exists the dont process the message. I was use Dynamo DB (AWS) with TTL enabled, thus with TTL my database autoclean every hour erasing old request.
I think it is the 15 second wait before replying, was also happening to me as Facebook auto retries when you don't reply fast enough. Te EEe Te's idea is solid, write some mechanism to cache mids and check if it is a duplicate before processing

using Redis in Openstack Keystone, some Rubbish in redis

Recently, I'm using Redis to cache token for OpenStack Keystone. The function is fine, but some expired cache data still in Redis.
my Keystone config:
[cache]
enabled=true
backend=dogpile.cache.redis
backend_argument=url:redis://127.0.0.1:6379
[token]
provider = uuid
caching=true
cache_time= 3600
driver = kvs
expiration = 3600
but some expired data in Redis:
Data was over expiration time, but still in here, because the TTL is -1.
My question:
How can I change settings to stop this rubbish data created?
Is some gracefully way to clean it up?
I was trying to use command 'keystone-manage token_flush', but after reading code, I realized this command just clean up the expired tokens in Mysql
I hope this question still relevant.
I'm trying to do the same thing as you are, and for now the only option I found working is the argument on dogpile.cache.redis: redis_expiration_time.
Checkout the backend dogpile.redis API or source code.
http://dogpilecache.readthedocs.io/en/latest/api.html#dogpile.cache.backends.redis.RedisBackend.params.redis_expiration_time
The only problem with this argument is that it does not let you choose a different TTL for different categories, for example you want tokens for 10 minutes and catalog for 24 hours or so. The other parameters on keystone.conf just don't work from my experience (expiration_time and cache_time on each category)... Anyway this problem isn't relevant if you are using redis to store only keystone tokens.
[cache]
enabled=true
backend=dogpile.cache.redis
backend_argument=url:redis://127.0.0.1:6379
// Add this line
backend_argument=redis_expiration_time:[TTL]
Just replace the [TTL] with your wanted ttl and you'll start noticing keys with ttl in redis and after a while you will see that they are no more.
about the second question:
This is maybe not the best answer you'll see, but you can use OBJECT idletime [key] command on redis-cli to see how much time the specific key wasn't used (even GET reset idletime). You can delete the keys that have bigger idletime than your token revocation using a simple script.
Remember that the data on Redis isn't persistent data, meaning you can always use FLUSHALL and your OpenStack and keystone will work as usual, but ofc the first authentications will take longer.

CAKEPHP Reset cookieTimeout on activity

I have problem to make my application is not logged out user on activity
I have code like the picture above
as we know, modify the cakephp session is able by that code
"timeout" values is used to set how long session will be expired in a minutes. and the "autoRegenerate" value is used to renew the timeout value
and the last is "cookieTimeout" is used to set how long activity allowed
the crux of my question is how to auto regenerated the cookieTimeout cakephp in core.php (like renew "timeout" value with "autoRegenerate" => true)
Thanks in advance

Resources