我正在尝试使用GenServer在Elixir中编写一个八卦模拟器。我有一个main()方法,它充当创建网络拓扑的客户端并启动所有参与者(GenServer的)。然后,它将Genserver.cast()
发送给Actor以启动八卦。演员在其handle_cast()
中开始Task.start()
,开始与其他演员闲聊。似乎我没有以正确的方式使用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
都没有启动异步任务。
答案 0 :(得分:0)
GenServer.cast/3
和Task.start/1
都不会阻止您的应用程序退出。
我不确定为什么要构建一个escript
来测试代码。您可以使用以下选项等待执行完成再退出(包括但不限于):
•创建一个Application
•启动链接的任务,并在代码中的某处使用Task.await/2
等待任务完成。