Last active
March 1, 2017 14:48
-
-
Save jan-g/82e0c86c4accd722de30a638f56f8e3d to your computer and use it in GitHub Desktop.
"Priority" mailbox implementation (from Seven Chapters and Matt's Trousers in Some Weeks)
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 MyPriority do | |
# Despite racking up some other messages first, | |
# the initial loop only picks the "go" message | |
def loop do | |
IO.puts "in main loop" | |
receive do | |
{:go} -> | |
IO.puts "going" | |
loop2 | |
end | |
end | |
def loop2 do | |
IO.puts "in secondary loop" | |
receive do | |
{a} -> | |
IO.puts "got #{a}" | |
loop2 | |
end | |
end | |
def run do | |
IO.puts "running" | |
pid = spawn(MyPriority, :loop, []) | |
send pid, {:one} | |
send pid, {:two} | |
send pid, {:three} | |
send pid, {:go} | |
send pid, {:four} | |
end | |
# We can use this for a priority queue | |
def priority_loop do | |
receive do | |
{:priority, f} -> | |
apply(f, [:priority, :priority]) | |
priority_loop | |
after | |
0 -> | |
receive do | |
{x, f} -> | |
apply(f, [x, :other]) | |
priority_loop | |
end | |
end | |
end | |
# Here's a function that takes some time to run | |
def slow_function(p, from) do | |
IO.puts "in slow #{p} function called from #{from} loop" | |
:timer.sleep(:timer.seconds(1)) | |
IO.puts "exiting slow #{p} function" | |
end | |
def run_p do | |
pid = spawn(MyPriority, :priority_loop, []) | |
send pid, {:normal, &slow_function/2} | |
:timer.sleep(2) | |
send pid, {:normal, &slow_function/2} | |
send pid, {:priority, &slow_function/2} | |
send pid, {:normal, &slow_function/2} | |
send pid, {:priority, &slow_function/2} | |
IO.puts "Everything queued for priority mailbox saving the last messages" | |
:timer.sleep(:timer.seconds(7)) | |
IO.puts "Queueing final messages" | |
send pid, {:priority, &slow_function/2} | |
send pid, {:normal, &slow_function/2} | |
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
% iex | |
Erlang/OTP 18 [erts-7.3.1.2] [source] [64-bit] [smp:2:2] [async-threads:10] [kernel-poll:false] | |
Interactive Elixir (1.2.6) - press Ctrl+C to exit (type h() ENTER for help) | |
iex(1)> c("priority.ex") | |
hello.ex:1: warning: redefining module MyPriority | |
[MyPriority] | |
iex(2)> MyPriority.run | |
running | |
in main loop | |
going | |
in secondary loop | |
got one | |
{:four} <- return value from run/0 | |
in secondary loop | |
got two | |
in secondary loop | |
got three | |
in secondary loop | |
got four | |
in secondary loop | |
iex(3)> MyPriority.run_p | |
in slow normal function called from other loop | |
Everything queued for priority mailbox saving the last messages | |
exiting slow normal function | |
in slow priority function called from priority loop | |
exiting slow priority function | |
in slow priority function called from priority loop | |
exiting slow priority function | |
in slow normal function called from other loop | |
exiting slow normal function | |
in slow normal function called from other loop | |
exiting slow normal function | |
Queueing final messages | |
in slow priority function called from other loop | |
{:normal, #Function<6.115860663/2 in MyPriority.run_p/0>} <- return value from run_p/0 | |
exiting slow priority function | |
in slow normal function called from other loop | |
exiting slow normal function | |
iex(4)> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment