← Назад к вопросам

Pub/Sub система

2.3 Middle🔥 141 комментариев
#Брокеры сообщений#Конкурентность и горутины

Условие

Реализуйте простую систему Pub/Sub (publish/subscribe) с использованием каналов.

Интерфейс

type PubSub struct {
    // ваши поля
}

func NewPubSub() *PubSub
func (ps *PubSub) Subscribe(topic string) <-chan string
func (ps *PubSub) Publish(topic, message string)
func (ps *PubSub) Unsubscribe(topic string, ch <-chan string)
func (ps *PubSub) Close()

Требования

  • Несколько подписчиков на одну тему
  • Публикация сообщений всем подписчикам темы
  • Возможность отписки
  • Корректное закрытие всех каналов

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Pub/Sub система

Построим систему publish/subscribe с каналами.

Реализация

Основные компоненты:

  • RWMutex для синхронизации
  • map[string][]chan string для подписчиков по темам
  • Buffered каналы для неблокирующей отправки

Алгоритм Subscribe:

  1. Создаем новый канал размера 10
  2. Добавляем в список подписчиков темы
  3. Возвращаем канал клиенту

Алгоритм Publish:

  1. Получаем список подписчиков для темы
  2. Отправляем сообщение каждому с таймаутом
  3. Пропускаем медленных подписчиков

Алгоритм Unsubscribe:

  1. Ищем канал в списке подписчиков
  2. Удаляем из списка
  3. Закрываем канал

Алгоритм Close:

  1. Закрываем все каналы во всех темах
  2. Очищаем структуру данных

Сложность

  • Subscribe: O(1) - добавление в конец массива
  • Publish: O(n) где n - количество подписчиков
  • Unsubscribe: O(n) - поиск в массиве
  • Close: O(n*m) где n темы, m подписчики

Ключевые особенности

Buffered каналы: каждый канал размера 10 позволяет избежать блокировки издателя при отправке 10 сообщений

Non-blocking sends: используем select с таймаутом чтобы не блокировать если подписчик медлительный

RWMutex: используем для синхронизации доступа к структуре данных

Graceful close: при Close закрываем все каналы корректно

Потенциальные проблемы

Рace conditions: без RWMutex возможны race conditions при одновременных Subscribe и Publish

Memory leak: если забыть отписать, остаток в памяти

Deadlock: если не использовать select с таймаутом, медленный подписчик может заблокировать издателя

Panic на отправке в закрытый канал: нужно быть осторожным при Unsubscribe