Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
redissessionhandler.php
1<?php
2
4
8
10{
11 public const SESSION_REDIS_CONNECTION = 'session.redis';
12
14 protected $connection;
15 protected string $prefix;
16 protected bool $exclusiveLock;
17
18 public function __construct(array $options)
19 {
20 $this->readOnly = $options['readOnly'] ?? false; //defined('BX_SECURITY_SESSION_READONLY');
21 $this->prefix = $options['keyPrefix'] ?? 'BX'; //defined("BX_CACHE_SID") ? BX_CACHE_SID : "BX"
22 $this->exclusiveLock = $options['exclusiveLock'] ?? false; //defined('BX_SECURITY_SESSION_REDIS_EXLOCK') && BX_SECURITY_SESSION_REDIS_EXLOCK
23
24 $host = (string)($options['host'] ?? '127.0.0.1');
25 $port = (int)($options['port'] ?? 6379);
26 if (str_starts_with($host, 'unix://'))
27 {
28 $port = 0;
29 }
30
31 $connectionPool = Application::getInstance()->getConnectionPool();
32 $connectionPool->setConnectionParameters(self::SESSION_REDIS_CONNECTION, [
33 'className' => RedisConnection::class,
34 'host' => $host,
35 'port' => $port,
36 'servers' => $options['servers'] ?? [],
37 'serializer' => $options['serializer'] ?? null,
38 'failover' => $options['failover'] ?? null,
39 'timeout' => $options['timeout'] ?? null,
40 'readTimeout' => $options['readTimeout'] ?? null,
41 'persistent' => $options['persistent'] ?? null,
42 ]);
43 }
44
45 public function open($savePath, $sessionName): bool
46 {
47 return $this->createConnection();
48 }
49
50 public function close(): bool
51 {
52 parent::close();
53 $this->closeConnection();
54
55 return true;
56 }
57
58 public function processRead($sessionId): string
59 {
60 $result = $this->connection->get($this->getPrefix() . $sessionId);
61
62 return $result?: "";
63 }
64
65 public function processWrite($sessionId, $sessionData): bool
66 {
67 $maxLifetime = (int)ini_get("session.gc_maxlifetime");
68
69 $this->connection->setex($this->getPrefix() . $sessionId, $maxLifetime, $sessionData);
70
71 return true;
72 }
73
74 public function processDestroy($sessionId): bool
75 {
76 $isConnectionRestored = false;
77 if (!$this->isConnected())
78 {
79 $isConnectionRestored = $this->createConnection();
80 }
81
82 if (!$this->isConnected())
83 {
84 return false;
85 }
86
87 $this->connection->del($this->getPrefix() . $sessionId);
88
89 if ($isConnectionRestored)
90 {
91 $this->closeConnection();
92 }
93
94 return true;
95 }
96
97 public function gc($maxLifeTime): int
98 {
99 return 0;
100 }
101
102 protected function isConnected(): bool
103 {
104 return $this->connection !== null;
105 }
106
107 protected function getPrefix(): string
108 {
109 return $this->prefix;
110 }
111
112 protected function createConnection(): bool
113 {
114 $connectionPool = Application::getInstance()->getConnectionPool();
116 $redisConnection = $connectionPool->getConnection(self::SESSION_REDIS_CONNECTION);
117 if (!$redisConnection)
118 {
119 return false;
120 }
121
122 $this->connection = $redisConnection->getResource();
123
124 return $redisConnection->isConnected();
125 }
126
127 protected function closeConnection(): void
128 {
129 if ($this->isConnected())
130 {
131 $this->connection->close();
132 }
133
134 $this->connection = null;
135 }
136
137 public function updateTimestamp($sessionId, $sessionData): bool
138 {
139 return $this->write($sessionId, $sessionData);
140 }
141
142 protected function lock($sessionId): bool
143 {
144 $sid = $this->getPrefix();
145 $lockTimeout = 55;//TODO: add setting
146 $lockWait = 59000000;//micro seconds = 60 seconds TODO: add setting
147 $waitStep = 100;
148
149 $lock = 1;
150 if ($this->exclusiveLock)
151 {
152 $lock = Context::getCurrent()->getRequest()->getRequestedPage();
153 }
154
155 while (!$this->connection->setnx($sid . $sessionId . ".lock", $lock))
156 {
157 usleep($waitStep);
158 $lockWait -= $waitStep;
159 if ($lockWait < 0)
160 {
161 $errorText = '';
162 if ($lock !== 1)
163 {
164 $lockedUri = $this->connection->get($sid . $sessionId . ".lock");
165 if ($lockedUri && $lockedUri != 1)
166 {
167 $errorText .= sprintf(' Locked by "%s".', $lockedUri);
168 }
169 }
170
171 $this->triggerLockFatalError($errorText);
172 }
173
174 if ($waitStep < 1000000)
175 {
176 $waitStep *= 2;
177 }
178 }
179 $this->connection->expire($sid . $sessionId . ".lock", $lockTimeout);
180
181 return true;
182 }
183
184 protected function unlock($sessionId): bool
185 {
186 $this->connection->del($this->getPrefix() . "{$sessionId}.lock");
187
188 return true;
189 }
190}
static getCurrent()
Definition context.php:241