dsfsdf
This commit is contained in:
@@ -19,6 +19,10 @@ use PDO;
|
||||
|
||||
final class Router
|
||||
{
|
||||
private const BOOTSTRAP_MEASUREMENT_LIMIT = 150;
|
||||
private const BOOTSTRAP_SNAPSHOT_LIMIT = 40;
|
||||
private const LONG_REQUEST_BUDGET_SECONDS = 8.0;
|
||||
|
||||
private string $moduleBasePath;
|
||||
private ModuleConfig $config;
|
||||
private ?PDO $pdo = null;
|
||||
@@ -61,6 +65,7 @@ final class Router
|
||||
public function handle(string $relativePath): never
|
||||
{
|
||||
try {
|
||||
$this->configureRuntimeGuards();
|
||||
$this->releaseSessionLock();
|
||||
$method = strtoupper((string) ($_SERVER['REQUEST_METHOD'] ?? 'GET'));
|
||||
$path = trim($relativePath, '/');
|
||||
@@ -315,10 +320,10 @@ final class Router
|
||||
'purchased_miners' => [],
|
||||
'measurement_rates' => [],
|
||||
]);
|
||||
$measurements = $this->safeRead(fn () => $this->measurements($projectKey, $settings, false), []);
|
||||
$measurements = $this->safeRead(fn () => $this->bootstrapMeasurements($projectKey, $settings), []);
|
||||
$targets = $this->safeRead(fn () => $this->targets($projectKey), []);
|
||||
$dashboards = $this->safeRead(fn () => $this->dashboards($projectKey), []);
|
||||
$fxSnapshots = $this->safeRead(fn () => $this->measurementFxSnapshots($measurements), []);
|
||||
$fxSnapshots = $this->safeRead(fn () => $this->measurementFxSnapshots($measurements, self::BOOTSTRAP_SNAPSHOT_LIMIT), []);
|
||||
$summary = $this->safeRead(fn () => $this->analytics()->buildSummary($measurements, $settings, $targets), [
|
||||
'latest_measurement' => $measurements !== [] ? $measurements[array_key_last($measurements)] : null,
|
||||
'baseline' => $settings,
|
||||
@@ -326,6 +331,7 @@ final class Router
|
||||
'payouts' => [],
|
||||
'miner_offers' => [],
|
||||
]);
|
||||
$measurementCount = is_array($measurements) ? count($measurements) : 0;
|
||||
|
||||
return [
|
||||
'project' => $this->repository()->getProject($projectKey),
|
||||
@@ -336,7 +342,10 @@ final class Router
|
||||
'fx_snapshots' => $fxSnapshots,
|
||||
'summary' => $summary,
|
||||
'bootstrap_meta' => [
|
||||
'degraded' => false,
|
||||
'degraded' => $measurementCount >= self::BOOTSTRAP_MEASUREMENT_LIMIT,
|
||||
'measurement_limit' => self::BOOTSTRAP_MEASUREMENT_LIMIT,
|
||||
'snapshot_limit' => self::BOOTSTRAP_SNAPSHOT_LIMIT,
|
||||
'measurement_count' => $measurementCount,
|
||||
'duration_ms' => round((microtime(true) - $startedAt) * 1000, 2),
|
||||
],
|
||||
];
|
||||
@@ -773,6 +782,7 @@ final class Router
|
||||
throw new ApiException('Das Modul fx-rates ist nicht verfuegbar.', 422);
|
||||
}
|
||||
|
||||
$startedAt = microtime(true);
|
||||
module_fn('fx-rates', 'ensure_schema');
|
||||
$legacyRows = $this->repository()->listAllFxRates();
|
||||
$legacyFetches = $this->groupLegacyFxFetches($legacyRows);
|
||||
@@ -784,6 +794,7 @@ final class Router
|
||||
$migratedRates = 0;
|
||||
|
||||
foreach ($legacyFetches as $legacyFetchId => $legacyFetch) {
|
||||
$this->assertRequestWithinBudget($startedAt, 'Legacy-FX-Migration dauert zu lange.');
|
||||
$existing = $this->findExistingFxFetchForLegacy($fxRepository, $legacyFetch);
|
||||
if (is_array($existing) && !empty($existing['id'])) {
|
||||
$fetchIdMap[$legacyFetchId] = (int) $existing['id'];
|
||||
@@ -817,6 +828,7 @@ final class Router
|
||||
$unresolvedMeasurements = 0;
|
||||
|
||||
foreach ($measurements as $measurement) {
|
||||
$this->assertRequestWithinBudget($startedAt, 'Legacy-FX-Migration dauert zu lange.');
|
||||
$measurementId = is_numeric($measurement['id'] ?? null) ? (int) $measurement['id'] : 0;
|
||||
if ($measurementId <= 0) {
|
||||
continue;
|
||||
@@ -1133,6 +1145,12 @@ final class Router
|
||||
return $this->analytics()->enrichMeasurements($rows, $settings);
|
||||
}
|
||||
|
||||
private function bootstrapMeasurements(string $projectKey, array $settings): array
|
||||
{
|
||||
$rows = $this->repository()->listMeasurements($projectKey, self::BOOTSTRAP_MEASUREMENT_LIMIT);
|
||||
return $this->analytics()->enrichMeasurements($rows, $settings);
|
||||
}
|
||||
|
||||
private function createMeasurement(string $projectKey, array $input): array
|
||||
{
|
||||
$projectTimezone = $this->projectTimezone($projectKey);
|
||||
@@ -1981,10 +1999,15 @@ final class Router
|
||||
return $resolved;
|
||||
}
|
||||
|
||||
private function measurementFxSnapshots(array $measurements): array
|
||||
private function measurementFxSnapshots(array $measurements, ?int $limit = null): array
|
||||
{
|
||||
$snapshots = [];
|
||||
foreach ($measurements as $measurement) {
|
||||
$measurementPool = $measurements;
|
||||
if ($limit !== null && $limit > 0 && count($measurementPool) > $limit) {
|
||||
$measurementPool = array_slice($measurementPool, -$limit);
|
||||
}
|
||||
|
||||
foreach ($measurementPool as $measurement) {
|
||||
$fetchId = is_numeric($measurement['fx_fetch_id'] ?? null) ? (int) $measurement['fx_fetch_id'] : 0;
|
||||
if ($fetchId <= 0 || isset($snapshots[$fetchId])) {
|
||||
continue;
|
||||
@@ -2114,6 +2137,16 @@ final class Router
|
||||
Http::json($payload, $statusCode);
|
||||
}
|
||||
|
||||
private function configureRuntimeGuards(): void
|
||||
{
|
||||
if (function_exists('ignore_user_abort')) {
|
||||
@ignore_user_abort(false);
|
||||
}
|
||||
if (function_exists('set_time_limit')) {
|
||||
@set_time_limit(15);
|
||||
}
|
||||
}
|
||||
|
||||
private function releaseSessionLock(): void
|
||||
{
|
||||
if (PHP_SAPI === 'cli') {
|
||||
@@ -2125,6 +2158,13 @@ final class Router
|
||||
}
|
||||
}
|
||||
|
||||
private function assertRequestWithinBudget(float $startedAt, string $message): void
|
||||
{
|
||||
if ((microtime(true) - $startedAt) > self::LONG_REQUEST_BUDGET_SECONDS) {
|
||||
throw new ApiException($message, 503, ['timeout' => true]);
|
||||
}
|
||||
}
|
||||
|
||||
private function debugLatest(): array
|
||||
{
|
||||
$filePath = DebugState::latestFilePath();
|
||||
|
||||
Reference in New Issue
Block a user