Memory leaks 以不';不要制造事件
在Elixir 1.7.4上使用命令0.17.2构建的应用程序经常会耗尽内存。一项调查发现,内存泄漏似乎是由不断增加的聚合实例造成的,这些聚合实例从未停止过 该聚合接收由外部系统触发的命令。在某些情况下,Memory leaks 以不';不要制造事件,memory-leaks,elixir,cqrs,event-sourcing,commanded,Memory Leaks,Elixir,Cqrs,Event Sourcing,Commanded,在Elixir 1.7.4上使用命令0.17.2构建的应用程序经常会耗尽内存。一项调查发现,内存泄漏似乎是由不断增加的聚合实例造成的,这些聚合实例从未停止过 该聚合接收由外部系统触发的命令。在某些情况下,execute函数会返回一个事件,在其他一些情况下,应该忽略该命令,因此它会返回nil(如所述) 似乎每次返回nil而不是一个事件时,聚合实例都会不确定地保持活动状态。即使同时附加了超时和寿命,也会发生这种情况,这显然意味着其他事情: defmodule RemoteThing.Lifespan
execute
函数会返回一个事件,在其他一些情况下,应该忽略该命令,因此它会返回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
)
我怀疑这是以下方面的一个缺陷:
避免内存泄漏的一种方法是生成事件,即使没有人需要它。这将导致受污染的持久化事件存储而不是易失性内存,因此从长远来看可能会导致更大的问题
我现在正在寻找一种方法来停止聚合实例,以防
execute
函数返回nil
。我们将非常感谢您提出的每一个解决方案。这已经得到了解决,并将在中提供
拉动请求延长聚合寿命行为,以包括错误/1之后的和命令/1之后的回调
以前,您只需定义after_event/1
回调函数即可实现命令的.Aggregates.AggregateLifespan
行为:
defmodule BankAccountLifespan do
@behaviour Commanded.Aggregates.AggregateLifespan
def after_event(%BankAccountClosed{}), do: :stop
def after_event(_event), do: :infinity
end
现在,您还必须定义after\u command/1
和after\u error/1
回调函数:
defmodule BankAccountLifespan do
@behaviour Commanded.Aggregates.AggregateLifespan
def after_event(%BankAccountClosed{}), do: :stop
def after_event(_event), do: :infinity
def after_command(%CloseAccount{}), do: :stop
def after_command(_command), do: :infinity
def after_error(:invalid_initial_balance), do: :stop
def after_error(_error), do: :stop
end
after_命令/1
回调将允许您在没有生成事件时停止聚合。谢谢,很高兴知道。只要不发布修复程序,有什么解决办法吗?PR会合并成AICT,所以{:dep\u from\u git,git:https://github.com/elixir-lang/my_dep.git“}
应该足够好。作为一种解决方法,您可以潜在地使用本地注册表
(名为Commanded.Registration.LocalRegistry
)识别正在运行的聚合进程,并根据需要优雅地终止它们。
defmodule BankAccountLifespan do
@behaviour Commanded.Aggregates.AggregateLifespan
def after_event(%BankAccountClosed{}), do: :stop
def after_event(_event), do: :infinity
end
defmodule BankAccountLifespan do
@behaviour Commanded.Aggregates.AggregateLifespan
def after_event(%BankAccountClosed{}), do: :stop
def after_event(_event), do: :infinity
def after_command(%CloseAccount{}), do: :stop
def after_command(_command), do: :infinity
def after_error(:invalid_initial_balance), do: :stop
def after_error(_error), do: :stop
end