Сохранение большой карты в GenServer, это допустимый вариант использования?

Может ли это быть допустимым использованием GenServer:

Если process_id является user_id и он уникален. Процесс содержит результат запроса большой карты данных, которая генерируется через БД. Теперь, если сотни пользователей вошли в систему и запросили свою карту данных, все они сохраняются в своем собственном процессе, на который ссылается user_id, который является уникальным

Поэтому, запросив карту, я проверю, существует ли процесс с user_id (который является идентификатором процесса), и возьму его и передам его обратно пользователю, если нет, то я создам его и переведу в новое состояние.

теперь, если пользователь обновил свою карту, при обновлении я обязательно обновлю его или создам новую.

Спасибо за ваше руководство

3 ответа

Решение

Это совершенно верно, если у вас не зарегистрировано миллион пользователей. Обычно это выполняется в экосистеме Erlang с так называемыми пулами.

Основной принцип: вы ограничиваете размер пула процессов, скажем, до 100 (5000, независимо от того, в основном это зависит от вашей емкости HW) и используете любое приоритетное хранилище для новичков (самый старый умирает, если емкость превышает лимит.)

Вы могли бы рассмотреть сериализацию этих смещенных данных, или порождение новых узлов, или что-то еще. В общем, процесс, содержащий состояние, является предпочтительным решением в OTP, если вы не достигли предела памяти. В этом случае вы, вероятно, выбрали бы какое-то постоянное хранилище, такое как DETS или (лучше) Mnesia.

Стоит отметить, что эликсир обеспечивает Agent модуль для этой цели, но я никогда не использую его, потому что старый добрый GenServer является ИМХО более чистой концепцией.

Если ваш genserver не делает ничего, кроме хранения карты и ее возврата через API, возможно, не стоит создавать много процессов.

Вы можете просто использовать таблицу ets для этой цели или использовать модуль агента (ключ = идентификатор пользователя, значение = карта).

Как уже упоминалось, кто-то уже упоминал об этом где-то на форуме Elixir - для чистых государственных хранилищ используйте Agent, для чистых вычислений используйте Task - для всего промежуточного - GenServers!

Даже если в данный момент вам не нужны никакие вычисления, может показаться, что они вам понадобятся в ближайшем будущем - именно поэтому я остановлюсь на GenServer.

Другие вопросы по тегам