diff --git a/lib/async/idler.rb b/lib/async/idler.rb new file mode 100644 index 00000000..eecdfc4f --- /dev/null +++ b/lib/async/idler.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +# Released under the MIT License. +# Copyright, 2022, by Samuel Williams. + +module Async + class Idler + def initialize(parent: Task.current) + @parent = parent + @list = List.new + end + + def async(*arguments, parent: (@parent or Task.current), **options) + wait + + parent.async(*arguments, **options) + end + + def wait + + end + end +end \ No newline at end of file diff --git a/lib/async/scheduler.rb b/lib/async/scheduler.rb index 63e1245c..61a9c9e0 100644 --- a/lib/async/scheduler.rb +++ b/lib/async/scheduler.rb @@ -36,10 +36,14 @@ def initialize(parent = nil, selector: nil) @interrupted = false @blocked = 0 + @load = 0 @timers = ::Timers::Group.new end + # The load is the number of tasks that were ready to run in the last iteration of the event loop. + attr :load + def scheduler_close # If the execution context (thread) was handling an exception, we want to exit as quickly as possible: unless $! diff --git a/test.rb b/test.rb new file mode 100755 index 00000000..c37afbf0 --- /dev/null +++ b/test.rb @@ -0,0 +1,33 @@ +#!/usr/bin/env ruby + +require_relative 'lib/async' + +def measure_load(sample_duration = 1.0) + start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) + sleep(sample_duration) + duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time + + return (duration / sample_duration) - 1.0 +end + +def add_load(n = 100) + n.times do + Async do + while true + sleep 0.01 + end + end + end +end + +Async do |task| + while true + load = measure_load + puts "Load: #{sprintf("%0.3f%%", load * 100.0)} children: #{task.children&.size}" + + if load <= 0.01 + puts "Adding load..." + add_load + end + end +end