This is resolved and patched in the documentation: 
https://github.com/cakephp/docs/commit/23fc03c12c3eea8456e895c2696444e037cdcc56

Thanks!
/Lionel

On Thursday, 12 September 2013 10:23:21 UTC+8, Lionel Chan wrote:
>
> Hi All
>
> *Environment:*
> CakePHP version: *2.4.0 stable*
> latest PHP 5.3
>
> We just recently pushed our app to AWS Beanstalk with ElastiCache + RDS as 
> our combo session, and using the ComboSession technique described in 
> here<http://book.cakephp.org/2.0/en/development/sessions.html#creating-a-custom-session-handler>.
>  
> At first everything was ok, but then out of sudden, our app keep running 
> into some infinity loops that we can't really reproduce at that point of 
> time. What we can do is basically remove the cookie key from RDS, or clear 
> browser cookie. Clearly it has something to do with Session.
>
> So these are our sample error_logs:
>
> [Wed Sep 11 03:56:27 2013] [error] [client 10.251.91.107] PHP Fatal error: 
>  Maximum execution time of 60 seconds exceeded in 
> /var/app/current/lib/Cake/Model/Datasource/CakeSession.php on line 612
> [Wed Sep 11 04:00:49 2013] [error] [client 10.251.91.107] PHP Fatal error: 
>  Maximum execution time of 60 seconds exceeded in 
> /var/app/current/lib/Cake/Model/Datasource/CakeSession.php on line 612
> [Wed Sep 11 04:03:02 2013] [error] [client 10.251.91.107] PHP Fatal error: 
>  Maximum execution time of 60 seconds exceeded in 
> /var/app/current/lib/Cake/Model/Datasource/CakeSession.php on line 612
> .... repeating ....
> [Thu Sep 12 01:11:48 2013] [error] [client 10.251.91.107] PHP Fatal error: 
>  Maximum execution time of 60 seconds exceeded in 
> /var/app/current/lib/Cake/Model/Datasource/CakeSession.php on line 612
> [Thu Sep 12 01:13:50 2013] [error] [client 10.251.91.107] PHP Fatal error: 
>  Maximum execution time of 60 seconds exceeded in 
> /var/app/current/lib/Cake/Model/Datasource/CakeSession.php on line 612
> [Thu Sep 12 01:15:15 2013] [error] [client 10.251.91.107] PHP Fatal error: 
>  Allowed memory size of 268435456 bytes exhausted (tried to allocate 523800 
> bytes) in /var/app/current/lib/Cake/Model/Model.php on line 1368
>
> So apparently CakeSession is trying to session_start in a loop that it 
> can't resolve the session successfully.
>
> Then we found out one serious issue with the *ComboSession.php* mentioned 
> in the post 
> http://book.cakephp.org/2.0/en/development/sessions.html#creating-a-custom-session-handler,
>  
> that, let's say, if Cache lost the session data, and Cache::delete($id) 
> fails, parent::destroy() will simply won't be called to destroy expired 
> session.
>
> That says, we run into this kind of loop:
>
> *Let's assume Cache lost the session data, and RDS retained a piece of 
> expired session data:*
> 1. CakeSession::start()
> 2. CakeSession::_startSession() - session data get loaded from RDS because 
> Cache::read returns false
> 3. CakeSession::_checkValid()
> 4. CakeSession::_validAgentAndTime() - obviously timeout, we got an 
> invalid data here
> 5. CakeSession::destroy() - this calls destroy the session and trying to 
> call session_destroy()
> 6. ComboSession::destroy($id) - this calls attempted to destroy the 
> session data from Cache but failed (Memcache engine says not found!), and 
> since it's failed, parent::destroy() will never get triggered, and so *old 
> session data is survived*.
> 7. Go to step 1 and continues looping, and PHP will dies either the whole 
> memory get filled up or time out.
>
>
> To reproduce, we use this modified version of ComboSession to simulate the 
> problem: *(The following code is to demonstrate the bug, not a working 
> copy!)*
>
> <?php
> App::uses('DatabaseSession', 'Model/Datasource/Session');
>
> class ComboSession extends DatabaseSession implements 
> CakeSessionHandlerInterface {
>     public $cacheKey;
>
>     public function __construct() {
>         $this->cacheKey = Configure::read('Session.handler.cache');
>         parent::__construct();
>     }
>
>     // read data from the session.
>     public function read($id) {
>         $result = false; //simulate cache read fails
>         if ($result) {
>             return $result;
>         }
>         return parent::read($id);
>     }
>
> // write data into the session.
>     public function write($id, $data) {
>         $result = Cache::write($id, $data, $this->cacheKey);
>         if ($result) {
>             return parent::write($id, $data);
>         }
>         return false;
>     }
>
>     // destroy a session.
>     public function destroy($id) {
>         $result = false; //simulate Cache::delete fails
>         if ($result) {
>             return parent::destroy($id);
>         }
>         return false;
>     }
>
>     // removes expired sessions.
>     public function gc($expires = null) {
>         return Cache::gc($this->cacheKey) && parent::gc($expires);
>     }
> }
>
>
> And in the database, try modify your current session with time (in data), 
> and expires to a earlier time. You should run into infinity loop in the 
> next run.
>
> -----------------------------------
>
> In the end, we fix it by issue delete on both Cache and RDS session data 
> regardless if Cache succeed or not:
>
>     public function destroy($id) {
> //Delete, regardless of cache succeed or not (so to prevent infinity loop)
>         Cache::delete($id, $this->cacheKey);
>         return parent::destroy($id);
>     }
>
>
> *Suggestion: To prevent someone from having this issue again, I think 
> it's best if you can update your documentation at *
> http://book.cakephp.org/2.0/en/development/sessions.html#creating-a-custom-session-handler
> .
>
> Thanks!
> /Lionel 
>

-- 
Like Us on FaceBook https://www.facebook.com/CakePHP
Find us on Twitter http://twitter.com/CakePHP

--- 
You received this message because you are subscribed to the Google Groups 
"CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/cake-php.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to