From ac6d4119b7c07efeb874dbfd685faef53a93cc70 Mon Sep 17 00:00:00 2001 From: bscheshirwork Date: Tue, 30 Jan 2018 13:13:13 +0300 Subject: [PATCH] add microseconds to key of online users --- .travis.yml | 1 + docs/tests.md | 18 +++++++++--------- src/Session.php | 34 +++++++++++++++++++++++++++++----- tests/SessionTest.php | 18 +++++++++++++++++- tests/docker-compose.yml | 6 +++--- 5 files changed, 59 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8bf1cb5..8d42d41 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: php php: - 7.1 +- 7.2 sudo: false diff --git a/docs/tests.md b/docs/tests.md index 1c3f90a..92ea939 100644 --- a/docs/tests.md +++ b/docs/tests.md @@ -107,8 +107,8 @@ $config['databases']['redis']['hostname'] = 'redis'; language: php php: -- 7.0 - 7.1 +- 7.2 sudo: false @@ -186,9 +186,9 @@ PHPStorm, попробуйте её. version: '2' services: php: - image: bscheshir/codeception:php7.1.9-fpm-yii2 #contain phpunit + image: bscheshir/codeception:php7.2.1-fpm-alpine-yii2 #contain phpunit volumes: - - ..:/project #src and tests shared to container + - ..:/var/www/html #src and tests shared to container - ~/.composer/cache:/root/.composer/cache environment: TZ: Europe/Moscow @@ -197,7 +197,7 @@ services: depends_on: - redis redis: - image: redis:4.0.1-alpine + image: redis:4.0.7-alpine restart: always ports: - "6379" @@ -271,15 +271,15 @@ $ docker-compose -f ./tests/docker-compose.yml run --rm --entrypoint composer ph Например, вывод может выглядить так: ```sh -docker-compose://[/home/dev/projects/yii2-redis-session/tests/docker-compose.yml]:php/php /repo/vendor/phpunit/phpunit/phpunit --configuration /project/phpunit.xml.dist --teamcity -Testing started at 13:58 ... -PHPUnit 5.7.21 by Sebastian Bergmann and contributors. +Testing started at 13:10 ... +docker-compose://[/home/dev/projects/yii2-redis-session/tests/docker-compose.yml]:php/php /repo/vendor/phpunit/phpunit/phpunit --configuration /var/www/html/phpunit.xml.dist --teamcity +PHPUnit 6.5.1 by Sebastian Bergmann and contributors. -Time: 76 ms, Memory: 6.00MB +Time: 108 ms, Memory: 8.00MB -OK (24 tests, 48 assertions) +OK (26 tests, 52 assertions) Process finished with exit code 0 ``` \ No newline at end of file diff --git a/src/Session.php b/src/Session.php index 76a2ada..fc63752 100644 --- a/src/Session.php +++ b/src/Session.php @@ -54,7 +54,7 @@ public function writeSession($id, $data) if ($result && ($userIdentity = \Yii::$app->user->getIdentity(false) ?? false)) { $userIdentityId = $userIdentity->getId() ?? 0; $key = $this->keyUser($userIdentityId); - $result = (bool) $this->redis->zadd($key, 'CH', time(), $id); + $result = (bool) $this->redis->zadd($key, 'CH', $this->time(), $id); $result = $result && (bool) $this->redis->set($this->keySession($id), $userIdentityId); } @@ -105,8 +105,8 @@ public function removeExpired() if ($keys = $this->redis->keys($this->maskUser())) { foreach ($keys ?? [] as $key) { $this->redis->multi(); - $this->redis->zrangebyscore($key, '-inf', time() - $this->getTimeout()); - $this->redis->zremrangebyscore($key, '-inf', time() - $this->getTimeout()); + $this->redis->zrangebyscore($key, '-inf', $this->expiredTime()); + $this->redis->zremrangebyscore($key, '-inf', $this->expiredTime()); $exec = $this->redis->exec(); if ($sessionIds = $exec[0]) { $this->redis->del(...array_map(function ($sessionId){ @@ -168,6 +168,30 @@ public function getActiveSessions(): array return $sessions; } + /** + * Get the timestamp of the start of the request with microsecond precision. + */ + public function time() + { + return $_SERVER["REQUEST_TIME_FLOAT"]; + } + + /** + * Get the timestamp of the expiry of session + * @param bool $cached save first-time calculated value + * @return float + */ + public function expiredTime($cached = true) + { + if ($cached) { + return $this->expiredTimeCache ?: $this->expiredTimeCache = $this->time() - $this->getTimeout(); + } + + return $this->time() - $this->getTimeout(); + } + + protected $expiredTimeCache = null; + /** * Get internal key for store/read a sorted list of sessions * @param int $userIdentityId user identity id @@ -235,10 +259,10 @@ protected function prefixSession(): string private function getSessionIdsByKey(string $key, bool $withScores = false): array { if ($withScores) { - return $this->redis->zrevrangebyscore($key, time(), time() - $this->getTimeout(), 'WITHSCORES'); + return $this->redis->zrevrangebyscore($key, $this->time(), $this->expiredTime(), 'WITHSCORES'); } - return $this->redis->zrevrangebyscore($key, time(), time() - $this->getTimeout()); + return $this->redis->zrevrangebyscore($key, $this->time(), $this->expiredTime()); } /** diff --git a/tests/SessionTest.php b/tests/SessionTest.php index f2299ad..13c2bb2 100644 --- a/tests/SessionTest.php +++ b/tests/SessionTest.php @@ -74,6 +74,22 @@ public function sessionDataProvider() ]; } + public function testTime() + { + $this->mockWebApplication(); + $session = \Yii::$app->session; + $this->assertEquals($_SERVER["REQUEST_TIME_FLOAT"], $session->time()); + } + + public function testExpiredTime() + { + $this->mockWebApplication(); + $session = \Yii::$app->session; + $this->assertEquals($_SERVER["REQUEST_TIME_FLOAT"] - $session->getTimeout(), $session->expiredTime(), 0.0000004); + $expired = [$session->expiredTime(false), $session->expiredTime(false)]; + $this->assertEquals($expired[0], $expired[1], 0.0000004); + } + /** * Test write session * @dataProvider sessionDataProvider @@ -138,7 +154,7 @@ public function testGetOnlineUsers() /** @var \bscheshirwork\redis\Session $session */ $session = \Yii::$app->session; $this->assertTrue($session->writeSession($sessionId, $sessionData)); - $time[$key] = time(); + $time[$key] = $_SERVER["REQUEST_TIME_FLOAT"]; } } diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml index c4a64de..cc4da90 100755 --- a/tests/docker-compose.yml +++ b/tests/docker-compose.yml @@ -6,9 +6,9 @@ version: '2' services: php: - image: bscheshir/codeception:php7.1.9-fpm-yii2 #contain phpunit + image: bscheshir/codeception:php7.2.1-fpm-alpine-yii2 #contain phpunit volumes: - - ..:/project #src and tests shared to container + - ..:/var/www/html #src and tests shared to container - ~/.composer/cache:/root/.composer/cache environment: TZ: Europe/Moscow @@ -17,7 +17,7 @@ services: depends_on: - redis redis: - image: redis:4.0.1-alpine + image: redis:4.0.7-alpine restart: always ports: - "6379"