Last active
July 1, 2021 03:37
-
-
Save hieuphq/f949e2a7074b0f23edb5f7dee2ad2533 to your computer and use it in GitHub Desktop.
Scenarios using concurrency in elixir
This file contains 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 EtsCacheExample do | |
def init!(seed, table_name) when is_atom(table_name) do | |
case :ets.info(table_name) do | |
:undefined -> | |
:ets.new(table_name, [:set, :public, :named_table]) | |
_ -> | |
raise "ETS table with name #{table_name(pool_name)} already exists." | |
end | |
add(seed, pool_name) | |
end | |
def teardown(table_name) do | |
:ets.delete(table_name) | |
end | |
def add(value, table_name) do | |
:ets.insert_new(table_name, {value}) | |
end | |
def exists?(value, pool_name) do | |
case :ets.lookup(table_name, value) do | |
[] -> false | |
_ -> true | |
end | |
end | |
def retrieve_all(table_name) do | |
table_name | |
|> :ets.match({:"$1"}) | |
|> List.flatten() | |
end | |
end |
This file contains 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 FanInFanOutExample do | |
def send_notifications(notifications) do | |
notifications | |
# Spin a task per element | |
|> Enum.map(&Task.async(fn -> send_single_notification(&1) end) | |
# Await all of them | |
|> Enum.map(&Task.await/1) | |
end | |
def send_single_notification(notification) do | |
# ... | |
end | |
end |
This file contains 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 FireAndForgetExample.Application do | |
use Application | |
def start(_type, _args) do | |
children = [ | |
# Start the supervision tree under the OTP Application. | |
{Task.Supervisor, name: FireAndForgetExample.TaskSupervisor} | |
] | |
Supervisor.start_link(children, strategy: :one_for_one) | |
end | |
end | |
defmodule FireAndForgetExample.OtherModule do | |
def process_event(event) do | |
# Start the task under the supervision tree. | |
Task.Supervisor.start_child(FireAndForgetExample.TaskSupervisor, fn -> | |
send_slack_notification("Hey! We got an event!") | |
end) | |
event | |
|> do_something() | |
|> do_something_else() | |
end | |
end |
This file contains 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 SchedulingExample do | |
use GenServer | |
@default_minutes 3 | |
def start_link(args \\ []) do | |
GenServer.start_link(__MODULE__, to_map(args)) | |
end | |
defp to_map(args) do | |
%{ | |
minutes: Keyword.get(args, :minutes, @default_minutes), | |
forever: Keyword.get(args, :forever, true), | |
} | |
end | |
def init(%{minutes: minutes} = state) do | |
schedule_work(minutes) | |
{:ok, state} | |
end | |
def handle_info(:work, %{minutes: minutes, forever: forever} = state) do | |
# Do my work here ... | |
if forever do | |
schedule_work(minutes) | |
end | |
{:noreply, state} | |
end | |
defp schedule_work(minutes) do | |
milliseconds = to_milliseconds(minutes) | |
Process.send_after(self(), :work, milliseconds) | |
end | |
defp to_milliseconds(minutes) do | |
minutes | |
|> :timer.minutes() | |
|> Kernel.trunc() | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment