feat: add processor service with Redis-backed job queue

- Introduced a new `processor` service in the Docker Compose setup to handle face matching jobs.
- Configured Redis as a job queue and state management system for processing searches.
- Updated the backend to enqueue jobs and manage user locks using Redis.
- Added environment variables for Redis configuration and runtime paths.
- Created technical design documentation for the processor service outlining architecture, queue model, and search lifecycle.
- Updated package.json and package-lock.json to include dependencies for BullMQ and ioredis in the processor workspace.
- Added sample PKL files for local testing in the `test_pkl` directory.
This commit is contained in:
MaddoScientisto 2026-04-11 17:53:22 +02:00
commit bbb9c193ce
20 changed files with 1313 additions and 108 deletions

View file

@ -34,8 +34,6 @@ export const mockCatalog = {
};
const sessions = new Map();
const searches = new Map();
const results = new Map();
export function createSession(session) {
const sessionId = randomId('sess');
@ -49,62 +47,3 @@ export function createSession(session) {
export function getSession(sessionId) {
return sessions.get(sessionId) || null;
}
export function createSearch({ raceId, user, selfieName, returnUrl, lang }) {
const searchId = randomId('search');
searches.set(searchId, {
id: searchId,
raceId,
user,
selfieName,
returnUrl,
lang,
status: 'processing',
createdAt: Date.now(),
completedAt: null,
resultId: null,
matches: []
});
return searches.get(searchId);
}
export function getSearch(searchId) {
return searches.get(searchId) || null;
}
export function completeSearch(searchId) {
const search = searches.get(searchId);
if (!search) {
return null;
}
const race = mockCatalog[search.raceId];
const matches = (race?.photos || []).slice(0, Math.min(4, race?.photos?.length || 0));
const resultId = randomId('result');
results.set(resultId, {
id: resultId,
raceId: search.raceId,
raceName: race?.name || search.raceId,
userId: search.user.id,
returnUrl: search.returnUrl,
lang: search.lang,
matches,
createdAt: Date.now()
});
const completed = {
...search,
status: 'completed',
completedAt: Date.now(),
resultId,
matches
};
searches.set(searchId, completed);
return completed;
}
export function getResult(resultId) {
return results.get(resultId) || null;
}