Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory leaks 以不';不要制造事件_Memory Leaks_Elixir_Cqrs_Event Sourcing_Commanded - Fatal编程技术网

Memory leaks 以不';不要制造事件

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

在Elixir 1.7.4上使用命令0.17.2构建的应用程序经常会耗尽内存。一项调查发现,内存泄漏似乎是由不断增加的聚合实例造成的,这些聚合实例从未停止过

该聚合接收由外部系统触发的命令。在某些情况下,
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