【发布时间】:2019-03-04 23:15:23
【问题描述】:
我正在尝试使用 GenServer 在 Elixir 中编写一个 Gossip Simulator。我有一个 main() 方法,它充当创建网络拓扑的客户端并启动所有参与者(GenServer 的)。然后它向一个 Actor 发送一个Genserver.cast() 来发起八卦。 Actor 在其handle_cast() 中启动一个Task.start() 以开始与其他actor 闲聊。看起来我没有以正确的方式使用Task.start()(actor.ex 中的第 16 行),因为被调用的任务 startGossiping() 永远不会执行,Task.start() 之后的语句也不会执行。混合只是退出而不给出任何错误。缩短的程序如下所示。
actor.ex -
defmodule Actor do
use GenServer
def init([nodeId, neighborList, algorithm]) do
inspect "#{nodeId}"
recCount = 1
gossipingTask = 0
{:ok, {nodeId, neighborList, algorithm, recCount, gossipingTask}}#nodeId, neighborList, algorithm, receivedCount
end
def handle_cast({:message, rumour}, state) do
{nodeId, neighborList, algorithm, recCount, gossipingTask} = state
IO.puts "nodeId - #{nodeId} recCount - #{recCount} handle_cast: #{rumour} gossipingTask - #{gossipingTask}"
nL = elem(state, 1)
IO.puts "here #{rumour}"
gossipingTask = Task.start(fn -> startGossiping(nL, rumour) end)
IO.puts "Now again - #{rumour}"
{:noreply, {nodeId, neighborList, algorithm, recCount + 1, gossipingTask}}
end
def startGossiping(nL, rumour) do
IO.puts "In startGossiping "
#{Enum.random(nL)}"
# GenServer.cast(Proj2.intToAtom(Enum.random(nL)), {:message, rumour})
end
end
proj2.ex -
defmodule Proj2 do
# Instructions to run the project
# 1) $mix escript.build
# 2) $escript proj2 100 full gossip
def main(args) do
# Receive total number of nodes, topology, algorithm, triggerNodes(optional), threshold(optional) from user.
# Read README.md for more details
numOfNodes = String.to_integer(Enum.at(args, 0))
topology = Enum.at(args, 1)
algorithm = Enum.at(args, 2)
numOfNodes = if String.contains?(topology, "2d"), do: round(:math.pow(round(:math.sqrt(numOfNodes)), 2)), else: numOfNodes
case topology do
"full" ->
Enum.each 1..numOfNodes, fn nodeId ->
neighborList = getNeighborsFull(nodeId, numOfNodes)
inspect neighborList
nodeId_atom = intToAtom(nodeId)
GenServer.start_link(Actor, [nodeId, neighborList, algorithm], name: nodeId_atom)
# IO.puts "In main, nodeId = #{nodeId}"
end
end
GenServer.cast(intToAtom(2), {:message, "This is Elixir Gossip Simulator"})
end
def getNeighborsFull(nodeId,numOfNodes) do
range = 1..numOfNodes
range
|> Enum.filter(fn(value) -> value != nodeId end)
|> Enum.map(fn(filtered_value) -> filtered_value * 1 end)
# IO.inspect Neighboringlist
end
def intToAtom(integer) do
integer |> Integer.to_string() |> String.to_atom()
end
end
更新:
还没弄清楚问题所在。我实际上无法启动任何并发进程。 spawn、start_link、Task 他们都没有启动异步任务。
【问题讨论】:
-
你想如何运行它?
-
1) $
mix escript.build2) $escript proj2 2 full gossip。输出 - nodeId - 2 recCount - 1 handle_cast: This is Elixir Gossip Simulator gossipingTask - 0 here This is Elixir Gossip Simulator $
标签: erlang elixir task distributed-computing distributed