🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

ztimer

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ztimer - rubygems Package Compare versions

Comparing version
0.5.0
to
0.6.0
+6
-1
.travis.yml
language: ruby
rvm:
- 2.2.1
- 2.2
before_install: gem install bundler -v 1.11.2
script:
- gem build ztimer.gemspec
- gem install ztimer --local
- bundle exec rspec

@@ -5,1 +5,5 @@ source 'https://rubygems.org'

gemspec
group :test do
gem 'lounger', '~> 0.2.0'
end
+92
-84

@@ -6,114 +6,122 @@ require "ztimer/version"

module Ztimer
@concurrency = 20
@watcher = Ztimer::Watcher.new(){|slot| execute(slot) }
@workers_lock = Mutex.new
@count_lock = Mutex.new
@queue = Queue.new
@running = 0
@count = 0
class Ztimer
@default_instance = nil
class << self
attr_reader :concurrency, :running, :count, :watcher, :queue
attr_reader :concurrency, :running, :count, :watcher, :queue
def async(&callback)
enqueued_at = utc_microseconds
slot = Slot.new(enqueued_at, enqueued_at, -1, &callback)
def initialize(concurrency: 20)
@concurrency = concurrency
@watcher = Ztimer::Watcher.new(){|slot| execute(slot) }
@workers_lock = Mutex.new
@count_lock = Mutex.new
@queue = Queue.new
@running = 0
@count = 0
end
incr_counter!
execute(slot)
def async(&callback)
enqueued_at = utc_microseconds
slot = Slot.new(enqueued_at, enqueued_at, -1, &callback)
return slot
end
incr_counter!
execute(slot)
def after(milliseconds, &callback)
enqueued_at = utc_microseconds
expires_at = enqueued_at + milliseconds * 1000
slot = Slot.new(enqueued_at, expires_at, -1, &callback)
return slot
end
add(slot)
def after(milliseconds, &callback)
enqueued_at = utc_microseconds
expires_at = enqueued_at + milliseconds * 1000
slot = Slot.new(enqueued_at, expires_at, -1, &callback)
return slot
end
add(slot)
def every(milliseconds, &callback)
enqueued_at = utc_microseconds
expires_at = enqueued_at + milliseconds * 1000
slot = Slot.new(enqueued_at, expires_at, milliseconds * 1000, &callback)
return slot
end
add(slot)
def every(milliseconds, &callback)
enqueued_at = utc_microseconds
expires_at = enqueued_at + milliseconds * 1000
slot = Slot.new(enqueued_at, expires_at, milliseconds * 1000, &callback)
return slot
end
add(slot)
def jobs_count
return @watcher.jobs
end
return slot
end
def concurrency=(new_value)
raise ArgumentError.new("Invalid concurrency value: #{new_value}") unless new_value.is_a?(Fixnum) && new_value >= 1
@concurrency = new_value
end
def jobs_count
return @watcher.jobs
end
def concurrency=(new_value)
raise ArgumentError.new("Invalid concurrency value: #{new_value}") unless new_value.is_a?(Fixnum) && new_value >= 1
@concurrency = new_value
end
def stats
{
running: @running,
scheduled: @watcher.jobs,
executing: @queue.size,
total: @count
}
end
protected
def stats
{
running: @running,
scheduled: @watcher.jobs,
executing: @queue.size,
total: @count
}
end
def add(slot)
incr_counter!
@watcher << slot
end
def incr_counter!
@count_lock.synchronize{ @count += 1 }
end
def self.method_missing(name, *args, &block)
@default_instance ||= Ztimer.new(concurrency: 20)
@default_instance.send(name, *args, &block)
end
def execute(slot)
@queue << slot
protected
@workers_lock.synchronize do
[@concurrency - @running, @queue.size].min.times do
@running += 1
start_new_thread!
end
def add(slot)
incr_counter!
@watcher << slot
end
def incr_counter!
@count_lock.synchronize{ @count += 1 }
end
def execute(slot)
@queue << slot
@workers_lock.synchronize do
[@concurrency - @running, @queue.size].min.times do
@running += 1
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?
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
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
begin
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
rescue ThreadError
puts "queue is empty"
end
@workers_lock.synchronize { @running -= 1 }
rescue ThreadError
puts "queue is empty"
end
worker.abort_on_exception = true
@workers_lock.synchronize { @running -= 1 }
end
worker.abort_on_exception = true
end
def utc_microseconds
return Time.now.to_f * 1_000_000
end
def utc_microseconds
return Time.now.to_f * 1_000_000
end
end
end
module Ztimer
class Ztimer
class Slot

@@ -39,2 +39,2 @@ attr_reader :enqueued_at, :expires_at, :recurrency, :callback

end
end
end
module Ztimer
class Ztimer
class SortedStore

@@ -97,2 +97,2 @@

end
end
end

@@ -1,3 +0,3 @@

module Ztimer
VERSION = "0.5.0"
class Ztimer
VERSION = "0.6.0"
end
module Ztimer
class Ztimer
class Watcher

@@ -95,2 +95,2 @@

end
end
end
# Ztimer
**Ztimer** is a Ruby gem that allows to get asynchronous delayed notifications. You can enqueue callbacks to be
called after some amount of time.
**Ztimer** is a simple Ruby implementation of an asynchronous timer, that allows to enqueue the execution of Ruby
code, so that it will be asynchronously executed on timeout. It's very useful when you need a simple way to execute
some code asynchronously or with a certain delay.
## Installation

@@ -49,12 +51,25 @@

# Custom Ztimer instance
my_timer = Ztimer.new(concurrency: 5) # create a new Ztimer instance
10.times do
# Use the custom ztimer to execute jobs asynchronously
my_timer.async do
puts "Doing async job..."
end
end
```
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.
executed at the same time, at most 20 of them will run concurrently. This is necessary in order to prevent uncontrolled threads spawn when many jobs have to be run 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 level by calling `Ztimer.concurrency = <concurrency>`, where `<concurrency>` is the maximum number of `Ztimer` workers allowed to run in parallel (ex: `Ztimer.concurrency = 50`).
If you're using custom **Ztimer** instance, you can specify the concurrency while creating the new instance:
```ruby
my_timer = Ztimer.new(concurrency: 42) # create a ztimer with concurrency set to 42
```
## 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.