Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Predis timeout #31

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

antriver
Copy link

This adds the ability to set an expiration time on the lock when using the Predis Redis driver.

It follows the procedure recommended in the Redis docs here: https://redis.io/commands/setnx

@antriver
Copy link
Author

Hi @arvenil

Thanks for this package.

I see you've made some significant changes in master. If there is any chance of this PR getting merged I will update it to reflect those changes. Could you let me know if it's worth me spending the time on that?

Currently I have merged master into my branch but due to the changes it's broken and should not be merged.

Thanks,
Anthony

@deminy
Copy link

deminy commented Nov 14, 2017

Few months ago I merged this PR manually ( you can see it from https://github.com/deminy/ninja-mutex ) and used it in some production environment for data migration (for tens of millions of records at least). Everything worked fine so I'd recommend to accept this PR. Thanks

Copy link
Owner

@arvenil arvenil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In short, I will take a look at this during the weekend.

try {
$this->releaseLock($name);
} catch (Exception $e) {
// Ignoring exceptions in destructor to not block shutdown.
}
Copy link
Owner

@arvenil arvenil Nov 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throwing exception in destructor was introduced in #4
This is an indicator that something went wrong and that the code didn't release mutex properly, which means you may end up with forever locked mutex.

That's being said, I understand that this PR also introduces solution for this problem for Predis implementation if timeout is used. However other cases, lack of timeout or just different implementations, still will be affected and if I remove this condition I will again have reports "my program crashed and your library didn't release the mutex" - with this error devs are at least aware of the problem.

I propose to actually throw here error (or warning), since e.g. hhvm doesn't like exception here. And maybe, just maybe, releaseLock should return true (ok), if we release lock with timeout - since timeout suggest that the lock eventually becomes available. Not saying that this is a solution, just saying my thoughts loud. Would you be ok if this code throws warning in such case? Are they still pain to handle in php?

Since you both guys are using this I will take a look into it and try to do my best to include this, I should have some time during the weekend.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a code review on the pull request from @antriver today, and here are what I think:

  1. Changes in class \NinjaMutex\Lock\PredisRedisLock do address the edge case in a proper way when locks are not correctly released automatically.

  2. When a lock is not released automatically as expected, the PredisRedisLock class can release the lock properly once the lock is expired. Because of that, changes in method _NinjaMutex\Mutex::_destruct() and _NinjaMutex\Lock\LockAbstract::_destruct() makes sense and make things smooth during execution (especially when handling massive locks). However, ignoring exceptions/errors silently doesn't seem to be a good practice since we lose visibility on them. To me, a better approach is to have a PSR-3 logger optionally attached to the package, log failures like that with the logger without throwing out a new exception. The external logger can be customized to throw out an exception in this case if needed. However, all these are about error reporting and error handling, which is not necessarily to be addressed and this PR.

My suggestion is to adopt changes for class \NinjaMutex\Lock\PredisRedisLock, and ignore changes in class NinjaMutex\Mutex and NinjaMutex\Lock\LockAbstract for now. Changes related to error reporting/handling can be addressed later on if needed. Thanks

@@ -22,8 +22,8 @@ public function getLockInformation()
$hostname = gethostname();

$params = array();
$params[] = $pid;
$params[] = $hostname;
$params['pid'] = $pid;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to give these keys because now that there can be different information providers the order, length, and contents of the lock values will vary. The predis lock adds an 'expiration' key to this so the structure needs to be known.
Plus it just makes sense to give these keys now that the data can be anything a provider wants to use.

@@ -20,10 +20,9 @@ class ResolvedHostnameLockInformationProvider extends BasicLockInformationProvid
*/
public function getLockInformation()
{
$params = parent::gatherInformation();
$params[] = gethostbyname(gethostname());
$params = parent::getLockInformation();
Copy link
Author

@antriver antriver Jul 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the parent call - gatherInformation does not exist.

$params = parent::gatherInformation();
$params[] = gethostbyname(gethostname());
$params = parent::getLockInformation();
$params['hostIp'] = gethostbyname(gethostname());
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a key the same as above in BasicLockInformationProvider

@antriver
Copy link
Author

Hi @arvenil and @deminy
I've remade this PR based on the latest master, and without the destructor/exception changes. Would you mind giving it another look?

@arvenil
Copy link
Owner

arvenil commented Jul 16, 2020

@antriver I'm ok with anything that doesn't brake tests, but travis test run is broken right now 🤷

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants