nicktacular / php-mongo-session

A PHP session handler with a Mongo DB backend.
MIT License
18 stars 6 forks source link

properly handle MongoCursorException on lock #6

Closed rocksfrow closed 10 years ago

rocksfrow commented 10 years ago

After adding write concern support, I found a problem with the current way the exceptions are being handled in lock().

RE: "may occur if there's a race to acquire a lock"

When using a write concern value that's too high, the wTimeoutMS value is essentially ignored with this behavior.

ex) I have two nodes, so w=2 works perfect. I decreased the wTimeoutMS to 5s, so when setting w=3 I should expect to get an exception... BUT, you are catching that exception and continuing to the next iteration. Because of this, instead of wTimeoutMS stopping script execution, it keeps running until either $config['locktimeout'] is exhausted, because it thinks it's simply retrying the lock.

I will investigate the exception scenarios and see if I can add some logic to differentiate between these two scenarios, so the script properly throws an exception when wTimeoutMS is exhausted.

rocksfrow commented 10 years ago

@nicktacular I am having trouble reproducing the MongoCursorException in this event. Is there any chance you have any recollection of the exception that was being caught in this scenario? Was it a write concern exception, or a MongoCursorException only?

I am thinking we should use something like this to properly catch the write concern "waiting for replication timed out" while still continuing on the exception you originally ran into.

                try {
                  $res = $this->locks->save($lock, $this->getConfig('write_options'));
                } catch (MongoWriteConcernException $e){
                  //catch write concern exception before general cursor exception                                                                                                                                    
                  die($e->getMessage());
                } catch (MongoCursorException $e) {
                  //may occur if there's a race to acquire a lock                                                                                                                                                    
                  continue;
                }

I just don't know the original exception you were handling and whether or not it's coming through as a writeconcern exception or not.

I could also check the exception code instead.

rocksfrow commented 10 years ago

I just realized this is the same block of code as #1

rocksfrow commented 10 years ago

https://github.com/rocksfrow/php-mongo-session/commit/083040fb2da55f4aa6dd5c115eda9bc90c4d696d

rocksfrow commented 10 years ago

Okay so I have code pushed up to my fork that takes care of this. The try/catch now handles the duplicate key that #1 was looking for with continue behavior, and breaks out of the loop for any other exception. Any exception other than the dup key should not be ignored.