Last active
April 11, 2019 06:15
-
-
Save tiagopog/1a9a8223331781de1b2845c3b6ae4ca7 to your computer and use it in GitHub Desktop.
Elixir - Processes (spawn, send, receive, Async, Agent)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Account do | |
defstruct name: nil, amount: 0 | |
def start(%Account{} = account) do | |
spawn fn -> run(account) end | |
end | |
defp run(account) do | |
account = receive do | |
{:debit, value} -> %{account | amount: account.amount - value} | |
{:credit, value} -> %{account | amount: account.amount + value} | |
{:show, caller} -> send(caller, account) | |
end | |
run(account) | |
end | |
end | |
# acc = Account.start(%Account{name: 'Tiago', amount: 100}) | |
# send(acc, {:debit, 10}) | |
# send(acc, {:show, self}) | |
# receive do | |
# value -> value | |
# after 1_000 -> IO.puts "No message received" | |
# end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Account do | |
defstruct name: nil, amount: 0 | |
def start(%Account{} = account) do | |
{:ok, pid} = Agent.start fn -> account end | |
pid | |
end | |
def credit(pid, value) do | |
Agent.update(pid, fn account -> | |
%{account | amount: account.amount + value} | |
end) | |
end | |
def debit(pid, value) do | |
Agent.update(pid, fn account -> | |
%{account | amount: account.amount - value} | |
end) | |
end | |
def show(pid) do | |
Agent.get(pid, fn account -> account end) | |
end | |
end | |
# acc = Account.start(%Account{name: 'Tiago', amount: 100}) | |
# Account.debit(acc, 20) | |
# Account.credit(acc, 10) | |
# Account.show(acc) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule AsyncTest do | |
@contents ["foo", "bar", "foobar"] | |
@output "async_test" | |
def run do | |
File.rm_rf!(@output) | |
File.mkdir_p!(@output) | |
@contents | |
|> Enum.with_index | |
|> Enum.map(&write_content_async(&1)) | |
|> Enum.map(fn _ -> | |
receive do | |
:ok -> :ok | |
{:error, reason} -> IO.puts :stderr, "Error: #{reason}" | |
after 3000 -> | |
IO.puts :stderr, "Timeout" | |
end | |
end) | |
end | |
def write_content_async(params) do | |
caller = self() | |
spawn(fn -> | |
seconds = :rand.uniform(10) * 1000 | |
:timer.sleep(seconds) | |
send(caller, write_content(params)) | |
end) | |
end | |
def write_content({content, index})do | |
IO.puts "Write \"#{content}\" into a file" | |
File.write("#{@output}/test_#{index + 1}.txt", content) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule AsyncTest2 do | |
@contents ["foo", "bar", "foobar"] | |
@output "async_test" | |
def run do | |
File.rm_rf!(@output) | |
File.mkdir_p!(@output) | |
@contents | |
|> Enum.with_index | |
|> Enum.map(&Task.async(fn -> | |
write_content(&1) | |
end)) | |
|> Enum.map(&Task.await/1) | |
end | |
def write_content({content, index}) do | |
seconds = :rand.uniform(5) * 1000 | |
:timer.sleep(seconds) | |
IO.puts "Write \"#{content}\" into a file" | |
File.write("#{@output}/test_#{index + 1}.txt", content) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Person do | |
@default_attrs %{name: nil} | |
def new(attrs) do | |
spawn fn -> | |
Map.merge(@default_attrs, attrs) |> run | |
end | |
end | |
defp run(attrs) do | |
receive do | |
:name -> IO.puts(attrs[:name]) | |
{:set_name, name} -> attrs = Map.merge(attrs, %{name: name}) | |
end | |
run(attrs) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment