Support » Plugin: Share Logins Across Multiple Sites » Sessions need to be destroyed

  • Resolved DeveloperWil

    (@developerwil)


    I have run a stack trace on a client site using this plugin and the pro version.

    We are seeing PHP-FPM child processes take 10 to 30 seconds and more to get a session. It seems to be waiting until the flock is released by the OS.

    lstat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
    lstat("/var/www/vhosts/URL_REDACTED/httpdocs/wp-content/plugins/share-logins/includes/Schedule.php", {st_mode=S_IFREG|0644, st_size=1093, ...}) = 0
    lstat("/var/www/vhosts/URL_REDACTED/httpdocs/wp-content/plugins/share-logins/includes", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
    lstat("/var/www/vhosts/URL_REDACTED/httpdocs/wp-content/plugins/share-logins", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
    lstat("/var/www/vhosts/URL_REDACTED/httpdocs/wp-content/plugins", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
    lstat("/var/www/vhosts/URL_REDACTED/httpdocs/wp-content", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
    lstat("/var/www/vhosts/URL_REDACTED/httpdocs", {st_mode=S_IFDIR|0750, st_size=4096, ...}) = 0
    lstat("/var/www/vhosts/URL_REDACTED", {st_mode=S_IFDIR|0710, st_size=4096, ...}) = 0
    lstat("/var/www/vhosts", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
    lstat("/var/www", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
    lstat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
    lstat("/var/www/vhosts/URL_REDACTED", {st_mode=S_IFDIR|0710, st_size=4096, ...}) = 0
    lstat("/var/www/vhosts", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
    lstat("/var/www", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
    lstat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
    open("/var/www/vhosts/URL_REDACTED/httpdocs/wp-content/plugins/share-logins/includes/Schedule.php", O_RDONLY) = 15
    fstat(15, {st_mode=S_IFREG|0644, st_size=1093, ...}) = 0
    fstat(15, {st_mode=S_IFREG|0644, st_size=1093, ...}) = 0
    fstat(15, {st_mode=S_IFREG|0644, st_size=1093, ...}) = 0
    mmap(NULL, 1093, PROT_READ, MAP_SHARED, 15, 0) = 0x7f3616e0b000
    munmap(0x7f3616e0b000, 1093)            = 0
    close(15)                               = 0
    open("/var/lib/php/session/sess_ht2uft2nq7nd0g3casrc8ge2vg", O_RDWR|O_CREAT|O_NOFOLLOW, 0600) = 15
    fstat(15, {st_mode=S_IFREG|0600, st_size=730, ...}) = 0
    getuid()                                = 10000
    flock(15, LOCK_EX^Cstrace: Process 13399 detached

    Can you please destroy the session in run() if there are no more tasks to schedule or perhaps have a redis setting that will allow redis to manage and store the data?

    Thanks,
    Wil.

Viewing 10 replies - 1 through 10 (of 10 total)
  • Plugin Author codexpert

    (@codexpert)

    Hi @developerwil,
    Thanks for pointing this out. We’ll fix this asap.

    Kind regards,
    codexpert
    https://codexpert.io

    Hi Codexpert
    I represent Wil’s client that is experiencing significant issues relating to the above matter.

    Can I ask when a fix is likely to be released?

    Thank you

    Neil Atwood

    Plugin Author codexpert

    (@codexpert)

    Hi @neilatw,
    Our dev team is working on it and hopefully can include this in the next version release – ETA early next month.

    Thanks

    Hi guys,
    Any advance on this issue?
    This is still regularly killing our site, and we are heading into our busy season.
    Would really like a permanent fix to this asap.

    Thanks

    Plugin Author Nazmul Ahsan

    (@mukto90)

    Hi @neilatw,
    We’ve released v2.1.2 today. Could you confirm if it resolves your issue?

    Thanks

    Hi @codexpert

    I have just run a code diff on 2.1.1 and 2.1.2 and the only difference I can see is that you are setting the remember parameter for wp cookies to true.

    This is not addressing the larger issue of the PHP sessions that you create in the /includes/Schedule/Schedule.php __construct() method.

    Nowhere in the code do you use session_destroy() to delete these php sessions which are running in each Apache child thread.

    Here is my amended code which seems to help the issue – notice I check to see if there are any scheduled URLs still to run and if not I destroy the created PHP session.

    <?php
    /**
     * All trigger facing functions
     */
    
    namespace codexpert\Share_Logins;
    
    /**
     * if accessed directly, exit.
     */
    if ( ! defined( 'ABSPATH' ) ) {
        exit;
    }
    
    /**
     * @package Plugin
     * @subpackage Schedule
     * @author Nazmul Ahsan <n.mukto@gmail.com>
     */
    class Schedule extends Hooks {
    
        /**
         * Constructor function
         */
        public function __construct( $plugin ) {
            $this->name     = $plugin['Name'];
            $this->ncrypt   = ncrypt();
            if ( session_status() == PHP_SESSION_NONE ) {
                session_start();
            }
        }
    
        public function run() {
            $_scheduled_urls = cx_get_scheduled_urls();
            if( is_array( $_scheduled_urls ) && count( $_scheduled_urls ) > 0 ) :
    
    		foreach ( $_scheduled_urls as $url ) {
    			echo "<script src='{$url}'></script>";
    
                if( defined( 'CXSL_DEBUG' ) && CXSL_DEBUG ) {
                    @parse_str( $url );
                    cx_add_log( 'trigger', 'outgoing', $this->ncrypt->decrypt( $user_login ), cx_get_route_home( $url ) );
                }
    		}
    
            cx_clean_scheduled_urls();
            endif;
            // ZPD 21/10/2019 - destroy session if scheduled URLs are empty
            if( empty( cx_get_scheduled_urls() ) ) {
                session_destroy();
            }
        }
    }
    

    Can you please pass this feedback to the developers and ask them to properly destroy PHP sessions that they are creating. It is causing a huge memory and php issue on my client’s server.

    The issue is critical to the point where we are now being forced to consider alternaitve SSO plugins.

    I’m happy to work with your devs in resolving this issue. You can find me at https://github.com/DeveloperWil

    Regards,
    Wil.

    Plugin Author Nazmul Ahsan

    (@mukto90)

    Thanks @developerwil. We’ll take a look at this.

    Having installed New Relic on the server to see why there is a huge resource uptake, I’ve found that session_start() is taking between 11 and 12 seconds to initiate.

    Because these are run through admin-ajax.php, they are effectively locking the PHP script from continuing, resulting in high memory usage and a timeout of the Apache child threads.

    This has been confirmed in these threads:
    https://stackoverflow.com/questions/13772074/session-start-takes-very-long-time
    http://konrness.com/php5/how-to-prevent-blocking-php-requests/

    — SNIP —
    Problem
    PHP writes its session data to a file by default. When a request is made to a PHP script that starts the session (session_start()), this session file is locked. What this means is that if your web page makes numerous requests to PHP scripts, for instance, for loading content via Ajax, each request could be locking the session and preventing the other requests from completing.

    The other requests will hang on session_start() until the session file is unlocked. This is especially bad if one of your Ajax requests is relatively long-running.

    Solution
    The session file remains locked until the script completes or the session is manually closed. To prevent multiple PHP requests (that need $_SESSION data) from blocking, you can start the session and then close the session. This will unlock the session file and allow the remaining requests to continue running, even before the initial request has completed.
    — END SNIP —

    I have modified the file
    share-logins\includes\functions.php
    line 181:

    if( ! function_exists( 'cx_set_scheduled_urls' ) ) :
    function cx_set_scheduled_urls( $urls ) {
        $_SESSION['_share-logins_scheduled_urls'] = base64_encode( serialize( $urls ) );
        // ZPD 23/11/2019 - close the session
        session_write_close();
    }
    endif;

    share-logins-pro\includes\functions.pgp
    line: 149

    if( ! function_exists( 'cx_set_scheduled_urls' ) ) :
    function cx_set_scheduled_urls( $urls ) {
        $_SESSION['_share-logins_scheduled_urls'] = base64_encode( serialize( $urls ) );
        // ZPD 23/11/2019 - close the session
        session_write_close();
    }

    To write close the session leaving it available to read.

    Ultimately it would work a lot faster if they were being stored in the DB.

    Regards,
    Wil.

    Plugin Author Nazmul Ahsan

    (@mukto90)

    Thanks @developerwil. We’re working on it and will include this in the next version release, ETA next week.

    Plugin Author codexpert

    (@codexpert)

    Hi @developerwil,
    Thanks for the heads up.

    As it’s an important issue, we’ve just released a newer version. Please update your plugin(s).

    Note: as a credit, we’ve mentioned your name in the code.

    Kind regards

Viewing 10 replies - 1 through 10 (of 10 total)
  • The topic ‘Sessions need to be destroyed’ is closed to new replies.