1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

wslでelixir その46

Last updated at Posted at 2023-09-05

概要

wsl(wsl2じゃない)で、elixirやってみた。
Cizen、やってみた。

参考にしたページ

手順

$ mix new testcizen

$ cd testcizen

defp deps do
	[
		{:cizen, "~> 0.14.1"}
	]
end

$ mix deps.get

$ iex -S mix

サンプルコード


defmodule BorrowChopstick do
	defstruct [:chopstick_id]
	use Cizen.Request
	defresponse LendChopstick, :request_id do
		defstruct [:request_id]
	end
end

defmodule ReturnChopstick do
	defstruct [:chopstick_id]
end

defmodule Chopstick do
	use Cizen.Automaton
	defstruct []
	alias Cizen.Effects.{Dispatch, Receive, Subscribe}
	alias Cizen.{Event, Filter}
	@impl true
	def spawn(id, %__MODULE__{}) do
		perform id, %Subscribe{
			event_filter: Filter.any([
				Filter.new(fn %Event{body: %BorrowChopstick{chopstick_id: ^id}} -> 
					true 
				end),
				Filter.new(fn %Event{body: %ReturnChopstick{chopstick_id: ^id}} -> 
					true 
				end)
			])
		}
		:available
	end
	@impl true
	def yield(id, :available) do
		received = perform id, %Receive{
			event_filter: Filter.new(fn %Event{body: %BorrowChopstick{}} -> 
				true 
			end)
		}
		alias BorrowChopstick.LendChopstick
		perform id, %Dispatch{
			body: %LendChopstick{
				request_id: received.id
			}
		}
		:not_available
	end
	@impl true
	def yield(id, :not_available) do
		perform id, %Receive{
			event_filter: Filter.new(fn %Event{body: %ReturnChopstick{}} -> 
				true 
			end)
		}
		:available
	end
end

defmodule Philosopher do
	use Cizen.Automaton
	defstruct [:name, :left_chopstick, :right_chopstick]
	alias Cizen.Effects.{Request, Dispatch}
	@impl true
	def spawn(_id, struct) do
		{:hungry, struct}
	end
	@impl true
	def yield(id, {:hungry, struct}) do
		%__MODULE__{
			name: name,
			left_chopstick: left_chopstick,
			right_chopstick: right_chopstick
		} = struct
		IO.puts("#{name} is hungry.")
		perform id, %Request{
			body: %BorrowChopstick{
				chopstick_id: left_chopstick
			}
		}
		IO.puts("#{name} has a chopstick in their left hand.")
		perform id, %Request{
			body: %BorrowChopstick{
				chopstick_id: right_chopstick
			}
		}
		IO.puts("#{name} has chopstics in both hands.")
		{:eating, struct}
	end
	@impl true
	def yield(id, {:eating, struct}) do
		%__MODULE__{
			name: name,
			left_chopstick: left_chopstick,
			right_chopstick: right_chopstick
		} = struct
		IO.puts("#{name} is eating.")
		perform id, %Dispatch{
			body: %ReturnChopstick{
				chopstick_id: left_chopstick
			}
		}
		perform id, %Dispatch{
			body: %ReturnChopstick{
				chopstick_id: right_chopstick
			}
		}
		{:hungry, struct}
	end
end

defmodule Dining do
	use Cizen.Effectful
	alias Cizen.Effects.{All, Start}
	def run do
		handle fn id ->
			chopstick_1 = perform id, %Start{saga: %Chopstick{}}
			chopstick_2 = perform id, %Start{saga: %Chopstick{}}
			chopstick_3 = perform id, %Start{saga: %Chopstick{}}
			chopstick_4 = perform id, %Start{saga: %Chopstick{}}
			chopstick_5 = perform id, %Start{saga: %Chopstick{}}
			philosophers = [
				%Philosopher{
					name: "Plato",
					left_chopstick: chopstick_1,
					right_chopstick: chopstick_2
				},
				%Philosopher{
					name: "Konfuzius",
					left_chopstick: chopstick_2,
					right_chopstick: chopstick_3
				},
				%Philosopher{
					name: "Socrates",
					left_chopstick: chopstick_3,
					right_chopstick: chopstick_4
				},
				%Philosopher{
					name: "Voltaire",
					left_chopstick: chopstick_4,
					right_chopstick: chopstick_5
				},
				%Philosopher{
					name: "Descartes",
					left_chopstick: chopstick_5,
					right_chopstick: chopstick_1
				}
			]
			perform id, %All{
				effects: Enum.map(philosophers, &(%Start{saga: &1}))
			}
			receive do
				_ -> 
					:ok
			end
		end
	end
end





実行結果

Interactive Elixir (1.13.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Dining.run
Plato is hungry.
Konfuzius is hungry.
Socrates is hungry.
Voltaire is hungry.
Descartes is hungry.
Plato has a chopstick in their left hand.
Konfuzius has a chopstick in their left hand.
Socrates has a chopstick in their left hand.
Voltaire has a chopstick in their left hand.
Descartes has a chopstick in their left hand.

BREAK: (a)bort (A)bort with dump (c)ontinue (p)roc info (i)nfo
       (l)oaded (v)ersion (k)ill (D)b-tables (d)istribution
a

以上。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?