如何使用 genServer 在 Elixir 上的消息代理中实现队列系统?

问题描述 投票:0回答:1

我可以使用什么方法使用 genServer 在 Elixir 中创建队列? 主要思想是生成创建长时间运行的流

def handle_call({:create_queue, queue_name}, _from, state) do

  create_queue(queue_name)
      {:reply, "You have successfully created a queue named #{queue_name}", state}

end

def create_queue(queue_name, list_of_subscribers \\ []) do

spawn fn -> create_queue_thread(list_of_subscribers, queue_name) end

end

我不知道如何仅知道队列的名称来访问队列。我想过返回它的 PID,但我不知道在哪里正确存储它以及之后如何使用它。我想到向所有队列流广播消息,并将其名称与包含其消息的元组进行模式匹配。

我在 gen_tcp 中实现了消息代理,并使用了包含队列名称和队列 pid 映射的超级进程,因此我可以使用发送功能。但是老师对我说“这非常糟糕”,我需要使用 genServer 而不是 gen_tcp 和基本的 Elixir 并发方法来重做我的任务。

def queue_cashier(queuing_process) do
    # IO.inspect(queuing_process)
    receive do
      { sender, queue_name } ->
        {queue_original,_} = Map.pop(queuing_process,queue_name)
        # IO.inspect(queuing_process)
        if queue_original == nil do
          # IO.puts("NIL")
          pid = spawn Server, :queue_handler, [%{}]
          queuing_process = Map.merge(queuing_process, %{queue_name => pid})
          # IO.inspect(queuing_process)
          # IO.inspect(pid)
          send sender, {pid }
          queue_cashier(queuing_process)
        else
          send sender, {queue_original }
          queue_cashier(queuing_process)
        end
        queue_cashier(queuing_process)
    end

    queue_cashier(queuing_process)
    end
elixir gen-server
1个回答
0
投票

但是老师对我说“这非常糟糕”,我需要重做我的 使用 genServer 而不是 gen_tcp 的任务和基本的 Elixir 并发 方法。

哈哈哈哈!嗯,基本的并发方法是

spawn()
send()
receive
。进程的邮箱实际上是一个 FIFO 实现,因为进程按照接收消息的顺序处理消息,所以只需复制进程邮箱的源代码即可!

我不太确定您的作业的详细信息是什么,但听起来您需要做的第一件事就是实现一个队列。 GenServer 可用于保存值,例如列表。列表的问题在于它本质上是一个 LIFO 实现——因为将东西添加到列表的头部是高效的,这意味着最后添加到列表的东西位于列表的头部,而且它也非常有效。有效地提取列表的头部。队列的一个简单的实现就是将东西存储在 GenServer 状态的列表中,然后当你需要一个值时,在

handle_call(:get_value...)
中你可以反转列表,然后获取反转列表的头,这提供了 FIFO实施。

如果队列需要存储进程,则将pid保存在列表中。

© www.soinside.com 2019 - 2024. All rights reserved.