Я пытаюсь написать симулятор сплетен на эликсире, используя GenServer.У меня есть метод main (), который действует как клиент, создающий топологию сети и запускающий всех участников (GenServer's).Затем он посылает Genserver.cast()
Актеру, чтобы инициировать сплетни.Актер в своем handle_cast()
начинает Task.start()
, чтобы начать сплетничать с другими актерами.Похоже, я не правильно использую Task.start()
(строка 16 в actor.ex), поскольку вызываемая задача startGossiping()
никогда не выполняется, а операторы после Task.start()
.Mix просто выходит без каких-либо ошибок.Сокращенная программа приведена ниже.
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
Ни один из них не запускает асинхронную задачу.