Elixir:分布式部落中GenServer的创建和注册以及调用其API之间的延迟

Elixir:分布式部落中GenServer的创建和注册以及调用其API之间的延迟,elixir,distributed-computing,Elixir,Distributed Computing,我正在使用Horde0.8.3来管理Elixir应用程序的分布式注册表和管理器。应用程序创建的UserAgent-s(简称UA)被实现为GenServer-s。每个UA代表一个连接到应用程序的用户。UAs是使用Horde.DynamicSupervisor.start_child(MyApi.DSup,{MyApi.UserAgent,user})创建的。在创建UA的同一个函数中,应用程序调用UA客户端API,例如UserAgent.ping(UA\u id)(此API的性质在这里并不重要)pi

我正在使用Horde0.8.3来管理Elixir应用程序的分布式注册表和管理器。应用程序创建的
UserAgent
-s(简称UA)被实现为
GenServer
-s。每个UA代表一个连接到应用程序的用户。UAs是使用Horde.DynamicSupervisor.start_child(MyApi.DSup,{MyApi.UserAgent,user})创建的。在创建UA的同一个函数中,应用程序调用UA客户端API,例如
UserAgent.ping(UA\u id)
(此API的性质在这里并不重要)
ping(…)
使用
通过_tuple
查找注册表中UA的
pid
,并向其发送
:ping
消息

应用程序在两个节点上启动,例如N1和N2。假设
start\u child(…)
ping()…
在N1上执行,而UA是在N2上创建的。当在这些条件下调用
ping(…)
时,大多数情况下它在部落注册表中找不到UA。我做了一些实验,发现UA在大约150到350毫秒(平均250毫秒)后就可以使用了(在部落中)

显然,Horde machine(deltaCRDT)在集群的所有节点上调度数据需要时间。该分派是在后台异步完成的

  • 对于在一台物理服务器上运行的应用程序来说,平均250毫秒似乎有点长(预计没有网络延迟),该服务器有12个内核,而注册表是空的。这是一个正常的延迟,还是我们应该多挖掘一点,看看是否有问题

  • 我本以为
    Horde.DynamicSupervisor.start\u child(…)
    是同步的,也就是说,它只在所有调度完成后返回,因为它应该具有与标准
    DynamicSupervisor
    相同的行为。这个假设正确吗?有没有办法进行同步调用

  • 最后,我实现了下面的函数
    get_pid(id,…)
    ,我调用该函数来获取UA的
    pid
    。这真的是一个好的解决方案吗

    def get_pid(_id, _wait, waited, max_wait) when waited > max_wait, do: :error
    
    def get_pid(id, wait, waited, max_wait) do
      Logger.debug("get_pid(#{id}, wait=#{wait}, waited=#{waited}, max_wait=#{max_wait})")
      case Horde.Registry.lookup(via_tuple(id)) do  [
        {pid, _}] ->
          Logger.debug("\t-> got pid=#{inspect pid}")
          pid
        [] ->
          Logger.debug("\t-> got []. Going for a nap for #{wait}ms")
          Process.sleep(wait)
          get_pid(id, wait*2, waited+wait, max_wait)
      end
    end
    

  • 事实上,我在上打开了一个案例,并得到了作者的确认,这是一种正常的行为。通过传递
    :delta_crdt_options
    选项(…),可以使用(…)
    sync_interval
    调整250ms左右的延迟