ztimer
Advanced tools
+47
-12
@@ -10,2 +10,3 @@ require "ztimer/version" | ||
| @workers_lock = Mutex.new | ||
| @count_lock = Mutex.new | ||
| @queue = Queue.new | ||
@@ -16,4 +17,14 @@ @running = 0 | ||
| class << self | ||
| attr_reader :concurrency, :running, :count | ||
| attr_reader :concurrency, :running, :count, :watcher, :queue | ||
| def async(&callback) | ||
| enqueued_at = utc_microseconds | ||
| slot = Slot.new(enqueued_at, enqueued_at, -1, &callback) | ||
| incr_counter! | ||
| execute(slot) | ||
| return slot | ||
| end | ||
| def after(milliseconds, &callback) | ||
@@ -48,9 +59,22 @@ enqueued_at = utc_microseconds | ||
| def stats | ||
| { | ||
| running: @running, | ||
| scheduled: @watcher.jobs, | ||
| executing: @queue.size, | ||
| total: @count | ||
| } | ||
| end | ||
| protected | ||
| def add(slot) | ||
| @count += 1 | ||
| incr_counter! | ||
| @watcher << slot | ||
| end | ||
| def incr_counter! | ||
| @count_lock.synchronize{ @count += 1 } | ||
| end | ||
@@ -63,19 +87,30 @@ def execute(slot) | ||
| @running += 1 | ||
| worker = Thread.new do | ||
| start_new_thread! | ||
| end | ||
| end | ||
| end | ||
| def start_new_thread! | ||
| worker = Thread.new do | ||
| begin | ||
| loop do | ||
| current_slot = nil | ||
| @workers_lock.synchronize do | ||
| current_slot = @queue.pop(true) unless @queue.empty? | ||
| end | ||
| break if current_slot.nil? | ||
| begin | ||
| while !@queue.empty? && (slot = @queue.pop(true)) do | ||
| slot.executed_at = utc_microseconds | ||
| slot.callback.call(slot) unless slot.callback.nil? | ||
| end | ||
| rescue ThreadError | ||
| # queue is empty | ||
| puts "queue is empty" | ||
| current_slot.executed_at = utc_microseconds | ||
| current_slot.callback.call(current_slot) unless current_slot.callback.nil? || current_slot.canceled? | ||
| rescue => e | ||
| STDERR.puts e.inspect + (e.backtrace ? "\n" + e.backtrace.join("\n") : "") | ||
| end | ||
| @workers_lock.synchronize { @running -= 1 } | ||
| end | ||
| worker.abort_on_exception = true | ||
| rescue ThreadError | ||
| puts "queue is empty" | ||
| end | ||
| @workers_lock.synchronize { @running -= 1 } | ||
| end | ||
| worker.abort_on_exception = true | ||
| end | ||
@@ -82,0 +117,0 @@ |
| module Ztimer | ||
| VERSION = "0.4.3" | ||
| VERSION = "0.5.0" | ||
| end |
+10
-7
@@ -35,2 +35,8 @@ # Ztimer | ||
| # Async execution | ||
| Ztimer.async do | ||
| # this code will be executed in background asyncronously | ||
| puts "Doing something useful in background..." | ||
| end | ||
| # Recurrent jobs | ||
@@ -46,13 +52,10 @@ job = Ztimer.every(delay) do # execute the block every second | ||
| By default **Ztimer** will run at maximum 20 notifications concurrently, so that if you have 100 notifications to be | ||
| executed at the same time, at maximum 20 of them will run at the same time. This is necessary in order to prevent uncontrolled | ||
| threads spawn when many notifications have to be sent at the same time. | ||
| By default **Ztimer** will run at maximum 20 jobs concurrently, so that if you have 100 jobs to be | ||
| executed at the same time, at maximum 20 of them will run at the same time. This is necessary in order to prevent uncontrolled threads spawn when many jobs have to be sent at the same time. | ||
| Anyway, you can change the concurrency by calling `Ztimer.concurrency = <concurrency>`, where `<concurrency>` is the maximum number | ||
| of `Ztimer` workers allowed to run in parallel (ex: `Ztimer.concurrency = 50`). | ||
| Anyway, you can change the concurrency by calling `Ztimer.concurrency = <concurrency>`, where `<concurrency>` is the maximum number of `Ztimer` workers allowed to run in parallel (ex: `Ztimer.concurrency = 50`). | ||
| ## Contributing | ||
| Bug reports and pull requests are welcome on GitHub at https://github.com/serioja90/ztimer. This project is intended to be a safe, | ||
| welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. | ||
| Bug reports and pull requests are welcome on GitHub at https://github.com/serioja90/ztimer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. | ||