Skip to content
20 changes: 18 additions & 2 deletions common/persistence/class.PhpRedisDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,19 @@ function connect($key, array $params)
$host = $params['host'];
$port = isset($params['port']) ? $params['port'] : self::DEFAULT_PORT;
$persist = isset($params['pconnect']) ? $params['pconnect'] : true;

$database = isset($params['database']) && is_int($params['database']) ? $params['database'] : 0;

if ($persist) {
$this->connection->pconnect($host, $port);
$uniqueConnectionKey = $host . $port . $database; // to prevent overriding connection to different db within same server
$this->connection->pconnect($host, $port, 0.0, $uniqueConnectionKey);
} else {
$this->connection->connect($host, $port);
}

if ($database) {
$this->connection->select($database);
}

if (isset($params['password'])) {
$this->connection->auth($params['password']);
}
Expand Down Expand Up @@ -110,4 +117,13 @@ public function keys($pattern) {
public function incr($key) {
return $this->connection->incr($key);
}

/**
* Returns keys number in active database
* @return int
*/
public function dbSize()
{
return $this->connection->dbSize();
}
}
90 changes: 71 additions & 19 deletions common/session/php/class.KeyValueSessionHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,39 +17,44 @@
* Copyright (c) 2013 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
*
*/
use oat\generis\model\data\event\SessionRead;
use oat\oatbox\Configurable;

/**
* Session implementation as a Key Value storage and using the persistence
*
*
* @author Joel Bout <joel@taotesting.com>
* @package generis
*/
class common_session_php_KeyValueSessionHandler extends Configurable
implements common_session_php_SessionHandler
class common_session_php_KeyValueSessionHandler extends Configurable implements common_session_php_SessionHandler
{
const OPTION_PERSISTENCE = 'persistence';
const OPTION_PERSISTENCE = 'persistence';

const KEY_NAMESPACE = "generis:session:";

/**
* @var common_persistence_KeyValuePersistence
*/
private $sessionPersistence = null;

protected function getPersistence() {
private $sessionPersistence;

/** @var \oat\oatbox\event\EventManager */
private $eventManager;

protected function getPersistence()
{
if (is_null($this->sessionPersistence)) {
$this->sessionPersistence = common_persistence_KeyValuePersistence::getPersistence($this->getOption(self::OPTION_PERSISTENCE));
}
return $this->sessionPersistence;
}

/**
* (non-PHPdoc)
* @see common_session_storage_SessionStorage::open()
*/
public function open($savePath, $sessionName){
return true;
public function open($savePath, $sessionName)
{
return true;
}

/**
Expand All @@ -67,7 +72,11 @@ public function close()
*/
public function read($id)
{
$session = $this->getPersistence()->get(self::KEY_NAMESPACE.$id);
$session = $this->getPersistence()->get(self::KEY_NAMESPACE . $id);

$event = new SessionRead();
$this->getEventManager()->trigger($event);

return is_string($session) ? $session : '';
}

Expand All @@ -76,16 +85,17 @@ public function read($id)
* @see common_session_storage_SessionStorage::write()
*/
public function write($id, $data)
{
return $this->getPersistence()->set(self::KEY_NAMESPACE.$id, $data, (int) ini_get('session.gc_maxlifetime'));
{
return $this->getPersistence()->set(self::KEY_NAMESPACE . $id, $data, $this->getTTL());
}

/**
* (non-PHPdoc)
* @see common_session_storage_SessionStorage::destroy()
*/
public function destroy($id){
$this->getPersistence()->del(self::KEY_NAMESPACE.$id);
public function destroy($id)
{
$this->getPersistence()->del(self::KEY_NAMESPACE . $id);
return true;
}

Expand All @@ -94,12 +104,54 @@ public function destroy($id){
* @see common_session_storage_SessionStorage::gc()
*/
public function gc($maxlifetime)
{
{
//
//problem here either
// solution 1 : do two explicit handlers for each specific persistence (Redis, SQL)
// solution 2 : Check if the eprsistence is capable of autonomous garbage
// solution 2 : Check if the persistence is capable of autonomous garbage collection
//
return true;
}

/**
* (non-PHPdoc)
* @see common_session_php_sessionStatisticsAware::getTotalActiveSessions()
*/
public function getTotalActiveSessions()
{
$persistence = $this->getPersistence();
if ($persistence->getDriver() instanceof common_persistence_PhpRedisDriver) {
return $persistence->getDriver()->dbSize();
}
common_Logger::d('Active sessions calculation not implemented');
return -1;
}

/**
* @return int
*/
private function getTTL()
{
return (int)ini_get('session.gc_maxlifetime');
}

/**
* @return \oat\oatbox\service\ServiceManager
*/
private function getServiceManager()
{
return \oat\oatbox\service\ServiceManager::getServiceManager();
}

/**
* @return \oat\oatbox\event\EventManager
*/
private function getEventManager()
{
if (!$this->eventManager) {
$this->eventManager = $this->getServiceManager()->get(\oat\oatbox\event\EventManager::SERVICE_ID);
}
return $this->eventManager;
}

}
34 changes: 34 additions & 0 deletions core/data/event/SessionRead.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php
/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2017 (original work) 2014 Open Assessment Technologies SA
*
*/

namespace oat\generis\model\data\event;


use oat\oatbox\event\Event;

class SessionRead implements Event
{

public function getName()
{
return __CLASS__;
}

}
75 changes: 75 additions & 0 deletions core/data/statistics/StatisticsManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace oat\generis\model\data\statistics;

use oat\generis\model\data\event\SessionRead;
use oat\oatbox\event\Event;
use oat\oatbox\service\ConfigurableService;
use oat\oatbox\service\ServiceManager;

/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2017 (original work) Open Assessment Technologies SA
*
*
*/
class StatisticsManager extends ConfigurableService
{
const SERVICE_ID = 'generis/statistics';
const OPTION_PERSISTENCE = 'persistence';

const KEY_LAST_ACCESS_TIME = 'generis:session:lastaccesstime';


/**
* @param Event $event
* @throws \common_Exception
* @throws \oat\oatbox\service\ServiceNotFoundException
*/
public static function catchEvent(Event $event)
{
if ($event instanceof SessionRead) {
$persistence = self::getPersistence();
if ($persistence) {
$persistence->set(self::KEY_LAST_ACCESS_TIME, time());
}
}
}

/**
* @param $key
* @return string
* @throws \oat\oatbox\service\ServiceNotFoundException
* @throws \common_Exception
*/
public function get($key)
{
return self::getPersistence()->get($key);
}

/**
* @return \common_persistence_KvDriver
* @throws \oat\oatbox\service\ServiceNotFoundException
* @throws \common_Exception
*/
private static function getPersistence()
{
$sm = ServiceManager::getServiceManager();
$persistenceOption = $sm->get(self::SERVICE_ID)->getOption(self::OPTION_PERSISTENCE);
return $sm->get(\common_persistence_Manager::SERVICE_ID)->getPersistence($persistenceOption);
}

}
3 changes: 2 additions & 1 deletion manifest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
'label' => 'Core',
'description' => 'Core extension, provide the low level framework and an API to manage ontologies',
'license' => 'GPL-2.0',
'version' => '3.27.0',
'version' => '3.28.0',
'author' => 'Open Assessment Technologies, CRP Henri Tudor',
'requires' => array(),
'models' => array(
Expand All @@ -51,6 +51,7 @@
'checks' => array(),
'php' => array(
oat\generis\scripts\install\TaskQueue::class,
\oat\generis\scripts\install\InstallStatisticsService::class,
),
),
'update' => 'oat\\generis\\scripts\\update\\Updater',
Expand Down
43 changes: 43 additions & 0 deletions scripts/install/InstallStatisticsService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace oat\generis\scripts\install;

use oat\generis\model\data\event\SessionRead;
use oat\generis\model\data\statistics\StatisticsManager;
use oat\oatbox\event\EventManager;
use oat\oatbox\extension\InstallAction;

/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2017 (original work) Open Assessment Technologies SA
*
*
*/
class InstallStatisticsService extends InstallAction
{

public function __invoke($params)
{
$statisticsPersistence = 'applicationStatistics';
\common_persistence_Manager::addPersistence($statisticsPersistence, ['driver' => 'phpfile']);// should be configure to redis-like shared persistence for multi-server configurations
$this->registerService(StatisticsManager::SERVICE_ID, new StatisticsManager([StatisticsManager::OPTION_PERSISTENCE => $statisticsPersistence]));

// $eventManager = $this->getServiceManager()->get(EventManager::SERVICE_ID);
// $eventManager->attach(SessionRead::class, [StatisticsManager::class, 'catchEvent']);
// $this->getServiceManager()->register(EventManager::SERVICE_ID, $eventManager);

}
}
10 changes: 10 additions & 0 deletions scripts/update/Updater.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
use oat\generis\model\fileReference\FileReferenceSerializer;
use oat\generis\model\fileReference\ResourceFileSerializer;
use oat\generis\model\kernel\persistence\smoothsql\search\ComplexSearchService;
use oat\generis\scripts\install\InstallStatisticsService;
use oat\oatbox\action\ActionService;
use oat\oatbox\event\EventManager;
use oat\oatbox\filesystem\FileSystemService;
Expand Down Expand Up @@ -313,6 +314,15 @@ public function update($initialVersion) {

$this->skip('3.10.0', '3.27.0');


if ($this->isVersion('3.27.0')) {
$action = new InstallStatisticsService();
$action->setServiceLocator($this->getServiceManager());
$action->__invoke([]);

$this->setVersion('3.28.0');
}

}

private function getReadableModelIds() {
Expand Down