Project

General

Profile

Actions

Task #6117

closed

Task #6116: EPIC: Speed up the stats updater daemon (scripts/workflow/update_stats.sh)

Reuse one IIKO session per command run instead of login/logout per request

Added by Redmine Admin about 9 hours ago. Updated about 9 hours ago.

Status:
Resolved
Priority:
Urgent
Assignee:
-
Start date:
08/26/2026
Due date:
% Done:

100%

Estimated time:

Description

Problem

Every IIKO fetcher opens a brand-new API session and closes it again around a single request:

  • IikoOlapV2RequestsFetchingService.fetchOlapDatafetchToken(...) at line 35, releaseToken(token) at line 56
  • DepartmentsFetchingService.fetchDepartments — same shape
  • IikoServerEmployeesFetchingService.fetchEmployees — same shape

So one logical OLAP data point costs three HTTP round-trips (/api/auth/api/v2/reports/olap/api/logout) plus two DB writes for the token row.

This is the real source of the "IIKO is single-threaded" symptom. IIKO licenses a limited number of concurrent API sessions; we spend that budget on our own login/logout churn, and the auth endpoint serialises.

A token cache already exists and is simply not used on this path: IikoAuthService.restoreToken()IikoAuthTokensService.findActiveAndExpireOthers(), with a 3-minute expiry stamped in IikoAuthTokensFetchingService.fetchToken. The OLAP fetcher bypasses IikoAuthService and calls IikoAuthTokensFetchingService directly.

Proposed change

Introduce a single session holder (e.g. IikoSessionService) that all fetchers go through:

  • hands out the current token, fetching a new one only when there is none or the stored expiration has passed (refresh a little early, e.g. 30s of slack);
  • refreshes and retries once when IIKO answers with an expired/invalid-token error;
  • releases the session once, at the end of the command run (JVM shutdown hook), not per request.

Then change IikoOlapV2RequestsFetchingService, DepartmentsFetchingService and IikoServerEmployeesFetchingService to use it, and drop their per-call fetchToken/releaseToken pairs.

Keep the login/hashedPassword override parameters working — they should get their own cached session keyed by login.

Acceptance

  • A run of iiko-stats-data-sync produces one /api/auth call per token lifetime, not one per OLAP request.
  • /api/logout is called once at the end of the run.
  • No behavioural change to the returned data.

Related issues 2 (1 open1 closed)

Related to Task #6120: Fix releaseToken: response body read twice, so IIKO sessions leakResolved08/26/2026

Actions
Blocks Task #6123: Gather metrics for companies/partners/users with a bounded worker poolFeedback08/26/2026

Actions
Actions #1

Updated by Redmine Admin about 9 hours ago

  • Blocks Task #6123: Gather metrics for companies/partners/users with a bounded worker pool added
Actions #2

Updated by Redmine Admin about 9 hours ago

  • Related to Task #6120: Fix releaseToken: response body read twice, so IIKO sessions leak added
Actions #3

Updated by Redmine Admin about 9 hours ago

  • Status changed from New to Resolved
  • % Done changed from 0 to 100

Реализовано в ветке speedup/stats-daemon, коммит 50a6ebef.

Новый IikoSessionService (adapters/iiko/server/authorization/common/services/):

  • currentToken(login, hashedPassword) — кэш по логину, новый токен только когда сессии нет или до expiration осталось меньше 30 с;
  • withToken(...) { token -> ... } — выполняет запрос и ровно один раз повторяет его с новым токеном, если iiko ответил «Token is expired or invalid» (ответ приходит текстом с кодом 200, поэтому распознаётся по телу — IikoSessionService.looksLikeExpiredToken);
  • releaseAll() под @PreDestroy — логаут один раз на выключении контекста Micronaut, а не после каждого запроса.

Переведены на него IikoOlapV2RequestsFetchingService, DepartmentsFetchingService, IikoServerEmployeesFetchingService — из них убраны парные fetchToken/releaseToken. Переопределение login/hashedPassword работает как раньше, кэш ключуется по логину.

Осталось за рамками этого коммита: ещё восемь фетчеров iiko живут по старой схеме — OlapDataFetchingService, EventsFetchingService, GroupsFetchingService, ProductsFetchingService, StoresFetchingService, TerminalsFetchingService, OutgoingInvoicesFetchingService, OlapPresetsFetchingService. Ни один из них не участвует в обороте демона, поэтому трогать их сейчас не стал, но лимит сессий у iiko они делят с остальными. Стоит отдельной задачи.

Проверка на живом iiko не проводилась — здесь нет доступа к серверу. Сборка проходит, тесты: 528/66 упавших и до, и после изменений (падения из-за отсутствующей фикстуры tmp/mock/iiko_logo_pass/iiko_auth.json, к этой задаче отношения не имеют).

Actions

Also available in: Atom PDF