Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
memcachesessionhandler.php
1<?php
2
4
8
10{
11 public const SESSION_MEMCACHE_CONNECTION = 'session.memcache';
12
14 protected $connection;
16 protected $prefix;
18 protected $exclusiveLock;
19
20 public function __construct(array $options)
21 {
22 $this->readOnly = $options['readOnly'] ?? false; //defined('BX_SECURITY_SESSION_READONLY');
23 $this->prefix = $options['keyPrefix'] ?? 'BX'; //defined("BX_CACHE_SID") ? BX_CACHE_SID : "BX"
24 $this->exclusiveLock = $options['exclusiveLock'] ?? false; //defined('BX_SECURITY_SESSION_MEMCACHE_EXLOCK') && BX_SECURITY_SESSION_MEMCACHE_EXLOCK
25
26 $connectionPool = Application::getInstance()->getConnectionPool();
27 $connectionPool->setConnectionParameters(self::SESSION_MEMCACHE_CONNECTION, [
28 'className' => MemcacheConnection::class,
29 'host' => $options['host'] ?? '127.0.0.1',
30 'port' => (int)($options['port'] ?? 11211),
31 'connectionTimeout' => $options['connectionTimeout'] ?? 1,
32 'servers' => $options['servers'] ?? [],
33 ]);
34
35 }
36
37 public function open($savePath, $sessionName): bool
38 {
39 $this->createConnection();
40
41 return $this->isConnected();
42 }
43
44 public function close(): bool
45 {
46 parent::close();
47 $this->closeConnection();
48
49 return true;
50 }
51
52 public function processRead($sessionId): string
53 {
54 $result = $this->connection->get($this->getPrefix() . $sessionId);
55
56 return $result?: "";
57 }
58
59 public function processWrite($sessionId, $sessionData): bool
60 {
61 $maxLifetime = (int)ini_get("session.gc_maxlifetime");
62
63 $this->connection->set($this->getPrefix() . $sessionId, $sessionData, 0, $maxLifetime);
64
65 return true;
66 }
67
68 public function processDestroy($sessionId): bool
69 {
70 $isConnectionRestored = false;
71 if (!$this->isConnected())
72 {
73 $isConnectionRestored = $this->createConnection();
74 }
75
76 if (!$this->isConnected())
77 {
78 return false;
79 }
80
81 $this->connection->replace($this->getPrefix() . $sessionId, "", 0, 1);
82
83 if ($isConnectionRestored)
84 {
85 $this->closeConnection();
86 }
87
88 return true;
89 }
90
91 public function gc($maxLifeTime): int
92 {
93 return 0;
94 }
95
96 protected function isConnected(): bool
97 {
98 return $this->connection !== null;
99 }
100
101 protected function getPrefix(): string
102 {
103 return $this->prefix;
104 }
105
106 protected function createConnection(): bool
107 {
108 $connectionPool = Application::getInstance()->getConnectionPool();
110 $memcacheConnection = $connectionPool->getConnection(self::SESSION_MEMCACHE_CONNECTION);
111 if (!$memcacheConnection)
112 {
113 return false;
114 }
115
116 $this->connection = $memcacheConnection->getResource();
117
118 return (bool)$this->connection;
119 }
120
121 protected function closeConnection(): void
122 {
123 if ($this->isConnected())
124 {
125 $this->connection->close();
126 }
127
128 $this->connection = null;
129 }
130
131 public function updateTimestamp($sessionId, $sessionData): bool
132 {
133 return $this->write($sessionId, $sessionData);
134 }
135
136 protected function lock($sessionId): bool
137 {
138 $sid = $this->getPrefix();
139 $lockTimeout = 55;//TODO: add setting
140 $lockWait = 59000000;//micro seconds = 60 seconds TODO: add setting
141 $waitStep = 100;
142
143 $lock = 1;
144 if ($this->exclusiveLock)
145 {
146 $lock = Context::getCurrent()->getRequest()->getRequestedPage();
147 }
148
149 while (!$this->connection->add($sid . $sessionId . ".lock", $lock, 0, $lockTimeout))
150 {
151 if ($this->connection->increment($sid . $sessionId . ".lock", 1) === 1)
152 {
153 $this->connection->replace($sid . $sessionId . ".lock", $lock, 0, $lockTimeout);
154 break;
155 }
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
180 return true;
181 }
182
183 protected function unlock($sessionId): bool
184 {
185
186 return $this->connection->replace($this->getPrefix() . "{$sessionId}.lock", 0, 0, 1);
187 }
188}
static getCurrent()
Definition context.php:241