3namespace Bitrix\Rest\Engine\Access;
5use Bitrix\Main\Config\Option;
7use Bitrix\Rest\OAuth\Client;
8use Bitrix\Main\Application;
11use Bitrix\Bitrix24\Feature;
19 private const MODULE_ID =
'rest';
20 private const BITRIX24_CONNECTOR_NAME =
'cache.redis';
21 private const CACHE_EXPIRE_TIME_PREFIX =
'expire';
22 private const DEFAULT_DOMAIN =
'default';
23 private static int $version = 2;
24 private static int $bucketSize = 60;
25 private static int $bucketCount = 10;
26 private static int $limitTime = 420;
27 private static float $minimalFixTime = 0.1;
28 private static string $domain =
'';
29 private static ?
bool $isActive =
null;
30 private static bool $isFinaliseInit =
false;
31 private static array $ignoreMethod = [
34 private static array $limitedEntityTypes = [
38 private static int $numBucket = 0;
39 private static array $timeRegistered = [];
48 if (Loader::includeModule(
'bitrix24'))
51 $seconds = (int)Feature::getVariable(
'rest_load_limiter_seconds');
59 $result = (int)Option::get(static::MODULE_ID,
'load_limiter_second_limit', static::$limitTime);
73 if (is_null(static::$isActive))
75 if (Loader::includeModule(
'bitrix24'))
77 static::$isActive =
true;
81 static::$isActive = Option::get(static::MODULE_ID,
'load_limiter_active',
'N') ===
'Y';
85 return static::$isActive;
88 private static function getDomain(): string
90 if (static::$domain ===
'')
92 if (Loader::includeModule(
'bitrix24') && defined(
'BX24_HOST_NAME'))
94 static::$domain = BX24_HOST_NAME;
98 static::$domain = static::DEFAULT_DOMAIN;
102 return static::$domain;
115 || in_array($entityType, static::$limitedEntityTypes,
true)
116 || !in_array(
$method, static::$ignoreMethod,
true)
120 if (!(static::$timeRegistered[
$key] ??
null))
122 static::$timeRegistered[
$key] = [
123 'entityType' => $entityType,
131 static::$timeRegistered[
$key][
'timeStart'][] = microtime(
true);
146 && in_array($entityType, static::$limitedEntityTypes,
true)
147 && !in_array(
$method, static::$ignoreMethod,
true)
151 if (static::$timeRegistered[
$key])
153 static::$timeRegistered[
$key][
'timeFinish'][] = microtime(
true);
156 if (!static::$isFinaliseInit)
158 static::$isFinaliseInit =
true;
159 Application::getInstance()->addBackgroundJob([__CLASS__,
'finalize']);
176 || !in_array($entityType, static::$limitedEntityTypes,
true)
177 || in_array(
$method, static::$ignoreMethod,
true)
184 if ($totalTime > static::getLimitTime())
186 if (Loader::includeModule(
'bitrix24') && function_exists(
'saveRestStat'))
188 saveRestStat(static::getDomain(), $entityType,
$entity,
$method, $totalTime);
197 private static function getKey($entityType,
$entity,
$method, $bucketNum =
null): string
200 static::getDomain() .
'|v' . static::$version .
'|'
219 if (static::isActive())
221 $resource = static::getConnectionResource();
224 $numBucket = static::getNumBucket();
226 $keyExpire = static::CACHE_EXPIRE_TIME_PREFIX .
'|' .
$key;
227 for (
$i = static::$bucketCount - 1;
$i >= 0;
$i--)
229 $time = (float)$resource->get(
$key . ($numBucket -
$i));
230 if (
$time > 0 && $resource->exists($keyExpire . ($numBucket -
$i)))
232 $result = (int)$resource->get($keyExpire . ($numBucket -
$i));
238 if (!empty(static::$timeRegistered))
240 $item = reset(static::$timeRegistered);
241 if (!empty($item[
'timeStart']))
243 $firstTimeStart = reset($item[
'timeStart']);
244 $result = $firstTimeStart + static::$bucketCount * static::$bucketSize;
256 if (!static::$numBucket)
258 static::$numBucket = intdiv(time(), static::$bucketSize);
261 return static::$numBucket;
275 if (static::isActive())
277 $numBucket = static::getNumBucket();
280 $resource = static::getConnectionResource();
283 for (
$i = 0;
$i < static::$bucketCount;
$i++)
288 if (!empty(static::$timeRegistered[
$key][
'timeStart']))
290 foreach (static::$timeRegistered[
$key][
'timeStart'] as
$k => $timeStart)
292 if (static::$timeRegistered[
$key][
'timeFinish'][
$k] ??
null)
294 $time = static::$timeRegistered[
$key][
'timeFinish'][
$k] - $timeStart;
295 if (
$time > static::$minimalFixTime)
314 if (static::$timeRegistered && static::isActive())
316 $resource = static::getConnectionResource();
319 foreach (static::$timeRegistered as $item)
322 $firstTime = reset($item[
'timeStart']);
323 foreach ($item[
'timeStart'] as
$k => $timeStart)
325 if ($item[
'timeFinish'][
$k])
327 $time += $item[
'timeFinish'][
$k] - $timeStart;
331 if (
$time > static::$minimalFixTime)
333 $key = static::getKey($item[
'entityType'], $item[
'entity'], $item[
'method'], static::getNumBucket());
334 if ($resource->exists(
$key))
340 $expireAt = $firstTime + static::$bucketCount * static::$bucketSize;
342 $resource->expire(
$key, $expireAt);
344 $keyExpire = static::CACHE_EXPIRE_TIME_PREFIX .
'|' .
$key;
345 $resource->incrByFloat($keyExpire, $expireAt);
346 $resource->expire($keyExpire, $expireAt);
350 static::$timeRegistered = [];
355 private static function getConnectionResource(): ?object
358 $connectionName = static::getConnectionName();
362 ->getConnectionPool()
363 ->getConnection($connectionName);
374 private static function getConnectionName(): string
376 if (Loader::includeModule(
'bitrix24'))
378 return static::BITRIX24_CONNECTOR_NAME;
static is($entityType, $entity, $method)
static registerStarting($entityType, $entity, $method)
static registerEnding($entityType, $entity, $method)
static getResetTime($entityType, $entity, $method)
static getRestTime($entityType, $entity, $method)
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
if(empty($signedUserToken)) $key