Приложению, созданному с Comaged 0.17.2 на Elixir 1.7.4, часто не хватает памяти.Исследование показало, что утечка памяти, по-видимому, вызвана растущим числом экземпляров агрегатов, которые никогда не останавливаются.
Рассматриваемый агрегат получает команды, запускаемые внешней системой.В некоторых случаях функция execute
возвращает событие, а в некоторых других случаях команда должна игнорироваться и поэтому возвращает nil
(как описано в docs ).
def execute(%RemoteThing{}, %ImportRemoteThing{deleted: true}), do: nil
Кажется, что каждый раз, когда возвращается nil
, а не событие, агрегатный экземпляр сохраняется живым неопределенно долго.Это происходит, несмотря на то, что привязаны тайм-аут и срок жизни, что явно подразумевает что-то еще:
defmodule RemoteThing.Lifespan do
@behaviour Commanded.Aggregates.AggregateLifespan
def after_event(_event), do: :stop
def after_command(_command), do: :stop
end
dispatch(
ImportRemoteThing,
to: RemoteThing,
lifespan: RemoteThing.Lifespan,
timeout: 15_000
)
Я подозреваю, что это ошибка в Comaged :
defp aggregate_lifespan_timeout(_context, []), do: :infinity
Одним из способов избежать утечки памяти может быть создание события, даже если оно никому не требуется.Это привело бы к загрязненному постоянному хранилищу событий вместо энергозависимой памяти и, следовательно, могло бы привести к еще большим проблемам в долгосрочной перспективе.
Сейчас я ищу способ остановить агрегатный экземпляр в случае, если execute
функция возвращает nil
.Любая идея обходного пути будет принята с благодарностью.