diary

I like Hatena Star with a text selection.

2020-09-18 - Ractor

pipe = Ractor.new { loop { Ractor.yield Ractor.recv } }

10.times.map do
  Ractor.new(pipe) do |pipe|
    loop do
      p pipe.take
    end
  end
end

100.times do |i|
  pipe << i
end

sleep 1

RactorでQueueをやる方法を笹田さんに教えてもらった。 pipeというRactorを作って、それでsendをyieldに変換するテクらしい。

ref: http://atdot.net/~ko1/activities/2020_ruby3summit.pdf


Ractorに渡すblockの中ではselfが代わるから、selfを使いたかったら適当に渡してやる必要があると知った。

class C
  def foo
    Ractor.new do
      bar # => NoMethodError
    end

    Ractor.new(self) do |this|
      this.bar # ok
    end
  end

  def bar
    p 'bar'
  end
end

C.new.foo

sleep 1

https://gist.github.com/pocke/23bbfe677210ba2dd5db7f0b646ed9bf

るりまのHTML生成をRactorで動かせないかためしたパッチ。 今の所↓のエラーが出てしまってそこで止まっている状態。

#<Thread:0x0000562a944ab540 run> terminated with exception (report_on_exception is true):
/home/pocke/ghq/github.com/rurema/bitclust/lib/bitclust/screen.rb:482:in `to_json': can not access non-sharable objects in constant JSON::SAFE_STATE_PROTOTYPE by non-main Ractor. (NameError)
        from /home/pocke/ghq/github.com/rurema/bitclust/lib/bitclust/screen.rb:482:in `breadcrumb_json_ld'
        from method.erb:10:in `method_template'
        from /home/pocke/ghq/github.com/rurema/bitclust/lib/bitclust/screen.rb:328:in `run_template'
        from /home/pocke/ghq/github.com/rurema/bitclust/lib/bitclust/screen.rb:642:in `body'
        from /home/pocke/ghq/github.com/rurema/bitclust/lib/bitclust/subcommands/statichtml_command.rb:331:in `create_html_file_p'
        from /home/pocke/ghq/github.com/rurema/bitclust/lib/bitclust/subcommands/statichtml_command.rb:319:in `create_html_method_file'
        from /home/pocke/ghq/github.com/rurema/bitclust/lib/bitclust/subcommands/statichtml_command.rb:275:in `block (2 levels) in create_html_methods'
        from /home/pocke/ghq/github.com/rurema/bitclust/lib/bitclust/subcommands/statichtml_command.rb:273:in `loop'
        from /home/pocke/ghq/github.com/rurema/bitclust/lib/bitclust/subcommands/statichtml_command.rb:273:in `block in create_html_methods'

やってることは次のような感じ

  • Enumerable#in_ractorsを定義して、eachが並列に動くようにした
  • ERB::NOT_GIVENというerb内部で引数を受け取ってないことを示す定数(中身はObject.new)がRactor内から触れなかったので適当なSymbolにした
  • URI.joinするのにこれまたURIが定数を触っていて動かなかったので、雑joinを実装した
  • interpolationがある正規表現はfrozenじゃないので、freezeした
  • クラス変数にキャッシュしているのをやめた
  • 現状ではまだイミュータブルなオブジェクトであっても子Ractorからは定数参照できないので、定数に入っているCHAR_TO_NAMEなどのハッシュをインライン展開した
  • DRb::DRbUndumpedをincludeするとMarshal.dumpできなくなるのだけど、Ractorのためにdumpしたいのでincludeをやめた
  • StatichtmlCommand@parserインスタンス変数がprocを持っててdumpできないので、使わないしnilで埋めた

https://gist.github.com/pocke/b5d5e402001cab5c7d83f38f185bc38b

ThreadでRactorっぽいインターフェイスを実装した。 こういうのがあるとRactorをRuby 2.7でも使いたい時にPolyfill的な感じで便利なのでは。


引越し業者を決めた。

twitter.com

不便…。自分で区の粗大ごみ回収を申し込んだ。引越し当日の朝に出さなきゃいけなくてギリギリ