LoginSignup
0
0

More than 1 year has passed since last update.

timers gemを読んだ

Last updated at Posted at 2022-02-01

個人的メモです

経緯

rubyの非同期タスクスケジューラーの#timeout_afterメソッドを実行したい。
https://docs.ruby-lang.org/en/master/Fiber/SchedulerInterface.html#method-i-timeout_after

このメソッドでは、「指定時間経過後に特定の処理を実行する」ことを非同期に行う。
(要は、指定時間が経つまでの間ブロックしないようにしたい)

この実装にあたり、以下のgemで実装されているschedlerの実装を参考にする(カンペする)ことにした。

このscheduler#timeout_after の実装は以下。
https://github.com/socketry/async/blob/main/lib/async/scheduler.rb#L283-L298

		# Invoke the block, but after the specified timeout, raise {TimeoutError} in any currenly blocking operation. If the block runs to completion before the timeout occurs or there are no non-blocking operations after the timeout expires, the code will complete without any exception.
		# @parameter duration [Numeric] The time in seconds, in which the task should complete.
		def timeout_after(timeout, exception = TimeoutError, message = "execution expired", &block)
			fiber = Fiber.current
			
			timer = @timers.after(timeout) do
				if fiber.alive?
					fiber.raise(exception, message)
				end
			end
			
			yield timer
		ensure
			timer.cancel if timer
		end
	end

このgemでは、タイマーを使用するイベントループの実行をtimers gem(作者同じ)に切り出している。
👉 timers gem を読むことにした。

実際に使ってみた

Timer::Group.newで、Timers::Groupを初期化する。
image.png
初期化されたtimersは、@events(@queue, @sequenceに入ったHandles)、@interval@timers@paused_timers をフィールドとして持つ。

Timers::Group#afterメソッドで、ブロックの実行を予約する。
引数として指定された時間より後に、初めてTimers::Group#fireメソッドを呼び出した時にそのブロックが実行されるようだ。
image.png

waitをすると次の一つ目のeventの実行が終了するまでブロックする。(実行するべきイベントがないときは即座にnilを返すようだ)
内部的には、Kernal#sleepを実行している。(👉task schedulerでは、このsleepを非同期に行なっているはず)
image.png

いまいち@timersが何なのか把握できていない
timers.afterなどで、新しくhandleを追加したときの返り値はTimer::Timerオブジェクト。
このtimerの#pause, #cancelなどを呼び出すことで、追加されたイベント(handle)の挙動の調整を行うことができる。
多分、ユーザー側にHandleは露出していなくて、基本的にtimerを介して登録されたイベントの調整を行う。
image.png
(TODO: ⏫なぜpauseしたのにfireで実行されるのだろう)

登場する主要モデル

その他メモ

上述の通り、マルチスレッドでなんとかしているとかいう話ではない。イベントの発生が起こらないかをブロッキングしてチェックしている。

0
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
0
0