ヽ(´・肉・`)ノログ

How do we fight without fighting?

Guildの発表資料を読んで思ったこと

Rubyと並列処理が好きで両方の良さそうな点を備えたElixirに触り始めたので,Rubyに並列処理を入れようとしているGuildに注目している. RubyKaigi2018での発表資料がPDFで公開されていたので読んだ.感想をここに書く.届けこの思い!

Classオブジェクトを拡張したときの挙動

33P で Class/Module objects が shareable になっている.そうしないとプログラミングが大変になるからいいと思う. ただ Ruby のオープンクラス機能を使ったときはクラスオブジェクトをコピーするのかなという点が気になった.たぶんそうかな.

class Greeting
  attr_reader :name

  def initialize(name)
    @name = name
  end

  def greet
    "hello, #{name}!"
  end
end

g1 = Guild.new do
  loop do
    name = Guild.receive
    Guild.parent << Greeting.new(name).greet
  end
end

g1 << "niku"
puts Guild.receive # => "hello, niku!" になりそう

class Greeting
  def greet
    "hi, #{name}!"
  end
end

g1 << "niku"
puts Guild.receive # => クラスオブジェクトが拡張されたらコピーされるだろうから "hello, niku!" のままになるのかなあ?

g2 = Guild.new do
  loop do
    name = Guild.receive
    Guild.parent << Greeting.new(name).greet
  end
end

g2 << "niku"
puts Guild.receive # => "hi, niku!" になりそう

g3 = Guild.new do
  class Greeting
    def greet
      "goodby, #{name}!"
    end
  end

  loop do
    name = Guild.receive
    Guild.parent << Greeting.new(name).greet
  end
end

g3 << "niku"
puts Guild.receive # => "goodby, niku!" になりそう
puts Greeting.new("niku").greet # => "hi, niku!" になりそう

返り値

ところで g1 << "niku"= の返り値はなんになるのかな. あまり使わないだろうから与えられた引数 =niku なんかでいいんだろうか.

timeout

Guild.receive には timeout が欲しいなあ.Erlang や Elixir の receive に after あるやつ.

Guild.new do
  x = Guild.receive
  Guild.parent << x
end

begin
  Guild.receive(timeout: 5000)
rescue GuildTimeout # 勝手に拡張した
  puts "timeout" # 5 秒後にここにきてほしい
end

プロセスのスケジューリングの公平さ

P49 Guildの実行スケジューラーはNativeなんですかね. ErlangVMのスケジューラーはNativeじゃないのはプロセスのスケジューリングを公平にするためだった気がするというのをどこかで読んだ気がする(要出展) NativeスレッドでもGuildの実行を公平にうまく制御できるのかな.

Guild内で起きたエラー

GuildでハンドリングしないエラーはGuild単位で止まりますかね.

g1 = Guild.new do
  x = Guild.receive
  if x == "boom!"
    raise "boom!"
  else
    Guild.parent << "done"
  end
end

begin
  g1 << "boom!"
  sleep 5
  # 子Guildでエラーになっても親Guildは影響を受けず動作を継続してほしいなあ.
  # 子Guildのスタックトレースとか取れた方がいいのかな.私は不要だと思う.
  puts "the parent works!"
rescue
  puts "the parent doesn't work..."
  p $!
end
# どうやって子Guildの状態を知ろう?
g1.alive? # => false とか?

感想

ささださん応援しております!