Сохранение большой карты в 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.