Back to questions
Middle+
6
Реализуйте менеджер событий, который принимает события в произвольном порядке и отправляет их в правильном порядке по ID (начиная с 1, каждый следующий на 1 больше). События могут приходить из нескольких каналов (channel), и порядок должен соблюдаться внутри каждого канала отдельно. Дубликаты событий нужно игнорировать. Для отправки использовать функцию sendEvent.
Companies where asked
А7-Технологии
Answer from AI
sobes.tech AI
Для решения задачи менеджера событий с поддержкой нескольких каналов и упорядочиванием событий по ID внутри каждого канала, можно использовать структуру данных, которая хранит для каждого канала:
- ожидаемый следующий ID события (начинается с 1)
- буфер для хранения пришедших событий с ID больше ожидаемого
- множество для отслеживания уже обработанных ID (чтобы игнорировать дубликаты)
При поступлении нового события:
- Проверяем, не был ли он уже обработан (по множеству).
- Если ID равен ожидаемому, отправляем событие и увеличиваем ожидаемый ID, затем проверяем буфер, есть ли следующие события подряд, и отправляем их по порядку.
- Если ID больше ожидаемого, кладём событие в буфер.
- Если ID меньше ожидаемого — игнорируем (дубликат или уже обработано).
Пример на JavaScript:
class EventManager {
constructor(sendEvent) {
this.sendEvent = sendEvent;
this.channels = new Map();
}
_getChannelState(channel) {
if (!this.channels.has(channel)) {
this.channels.set(channel, {
nextId: 1,
buffer: new Map(),
processed: new Set()
});
}
return this.channels.get(channel);
}
receiveEvent(channel, event) {
const state = this._getChannelState(channel);
const id = event.id;
if (state.processed.has(id)) {
// Дубликат
return;
}
if (id === state.nextId) {
this.sendEvent(channel, event);
state.processed.add(id);
state.nextId++;
// Проверяем буфер на последовательные события
while (state.buffer.has(state.nextId)) {
const nextEvent = state.buffer.get(state.nextId);
state.buffer.delete(state.nextId);
this.sendEvent(channel, nextEvent);
state.processed.add(state.nextId);
state.nextId++;
}
} else if (id > state.nextId) {
// Сохраняем в буфер
if (!state.buffer.has(id)) {
state.buffer.set(id, event);
}
}
// Если id < nextId — игнорируем
}
}
// Пример использования:
// const manager = new EventManager((channel, event) => console.log(`Send event ${event.id} from ${channel}`));
// manager.receiveEvent('channel1', {id: 2});
// manager.receiveEvent('channel1', {id: 1});
// manager.receiveEvent('channel1', {id: 2}); // дубликат, игнорируется