? ?
avatar stAn47
stAn47
3 Jun 2020

Introduction:
We are using Joomla with ecommerce extensions on highly visited sites. It seems that Joomla's session system is the largest bottleneck of Joomla performance and scalability, because it does not provide means to completely extend or override it without core modifications. Our goal is to provide:

  • a system which won't write session data to a file (or database) if there are no singnificant data (such as ecommerce cart or user login/account information)
  • a system which won't write a record into #__session table if it is not needed (for example when visited from googlebot or similar)
  • system which can not write session data at all (since new request will create a new session)
  • a system that can allow existing customer session read only (i.e. modifications allowed, but not written)
  • a system that can write session data to multiple servers and systems (replication)
  • a system that does properly session/request locks (right now only files sessions use proper locks)

with the current way of session implementation, each cookie-less (or cookie-ignorant - googlebot) visit creates a new session which creates a new entry in joomla's #__session table and also a new file when PHP files session handling is used. In many cases our customers are reaching 50 000 to 300 000 sessions a day due to the above reasons and you can easily imagine, this is a huge performance and replication problem.

For the above reasons i would like to suggest a simple workaround to allow 3rd party session handling properly:
\libraries\src\Factory.php

Updated function:

/**
	 * Create a session object
	 *
	 * @param   array  $options  An array containing session options
	 *
	 * @return  Session object
	 *
	 * @since   1.7.0
	 */
	protected static function createSession(array $options = array())
	{
		// Get the Joomla configuration settings
		$conf    = self::getConfig();
		$handler = $conf->get('session_handler', 'none');

		// Config time is in minutes
		$options['expire'] = ($conf->get('lifetime')) ? $conf->get('lifetime') * 60 : 900;

		// The session handler needs a JInput object, we can inject it without having a hard dependency to an application instance
		$input = self::$application ? self::getApplication()->input : new Input;
		
		$handlerClass = '\JSessionHandler'.ucfirst($handler); 
		if (class_exists($handlerClass)) {
			$sessionHandler = new $handlerClass($options); 
		}
		else {
			$sessionHandler = new \JSessionHandlerJoomla($options);
		}
		$sessionHandler->input = $input;

		$session = Session::getInstance($handler, $options, $sessionHandler);

		if ($session->getState() == 'expired')
		{
			$session->restart();
		}

		return $session;
	}

original joomla session handling always starts session with

$sessionHandler = new \JSessionHandlerJoomla($options);

regardless of configured session handler within the configuration.

thank you, best regards, stAn

avatar stAn47 stAn47 - open - 3 Jun 2020
avatar joomla-cms-bot joomla-cms-bot - labeled - 3 Jun 2020
avatar SharkyKZ SharkyKZ - change - 3 Jun 2020
Labels Added: ?
avatar SharkyKZ SharkyKZ - labeled - 3 Jun 2020
avatar mbabker
mbabker - comment - 3 Jun 2020

Nothing's going to change in 3.x at this point. You're going to have to core hack to get the result you want.

In 4.0, the session metadata can be turned off. That eliminates the queries at the start of every request when the session is started. As for the rest of what you're suggesting (no sessions for bots, read-only versus read-write, etc.) you would seriously be better off trying to implement your own frontend application and session service versus trying to patch these types of features into Joomla. The session service is started at a point in the request cycle where the only information it has out of your list is enough to decide "start the session with an in-memory provider instead of a persistent provider for a bot", so none of the read-only versus read-write bits could be handled efficiently.

As for the replication bit, you should be able to set Joomla to use Redis as the storage layer and configure that to handle the replication without Joomla needing to be able to handle that internally.

And on the locking part, it works for files because internally PHP's C code is dealing with file locks; looking around the ecosystem the only other place I've seen a session locking mechanism at the storage layer is Symfony's PDO handler.

avatar stAn47
stAn47 - comment - 3 Jun 2020

well,i hope you don't mean to swith my "frontend joomla application" to my "own frontend application" as i thought that we are here to make joomla better. i am not talking about 1 joomla site, i manage tens of servers with thousands of joomla sites that are hit with this issue (excessive session metadata rows and files data usage).

i will investigate the possiblities to take over session handling on j4 and see if it gets better there.

best regards, stan


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/29405.

avatar mbabker
mbabker - comment - 3 Jun 2020

well,i hope you don't mean to swith my "frontend joomla application" to my "own frontend application" as i thought that we are here to make joomla better.

You'd basically need your own implementation of Joomla\CMS\Application\SiteApplication which is the backbone of the frontend request cycle, I don't think you'd need to change anything about the session API (as that's not doing the metadata writing, it's coming from the application).

Like I said, a lot of the things you're looking for can't be wired up in a way that's generically usable because of the order of operations in executing the Joomla application (the session is started very early in the application bootup in trying to work out what plugins to load and certain frontend parameters (i.e. language) to use, which is well before any extensions are loaded, or the request has been routed anywhere; at that point it is pretty much impossible to efficiently say "this request requires a read-only interface to the session data, it will not write anything" or anything similar).
Realistically the only thing you could do is decide to not write a persistent session for a bot visitor, that can be gleaned based solely on request headers (but that relies on good User-Agent strings which are starting to become a hit-or-miss thing). With your own application class, you can tailor it to your needs much more efficiently than can be done in a mass distributed platform.

avatar nibra
nibra - comment - 30 Nov 2020

This proposal looks like an improvement to me. It supports the Open Closed Principle, as it allows to provide custom session handlers without the need to change core code. If not done already, this should be considered for J4.


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/29405.

avatar rdeutz rdeutz - change - 18 Dec 2020
Status New Closed
Closed_Date 0000-00-00 00:00:00 2020-12-18 10:36:47
Closed_By rdeutz
avatar rdeutz rdeutz - close - 18 Dec 2020

Add a Comment

Login with GitHub to post a comment