ztimer 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1e9203fd984c0ca9b608ec0a473f7653eee3a943
4
- data.tar.gz: 8c998b3131d0a6c969bdac9b994fcaf9beeefc32
3
+ metadata.gz: ba1fe46353cca7319d61150f6fe52622d3668db2
4
+ data.tar.gz: ac6dc6b45e0001d39e63a6ead7950b5db75ac7d0
5
5
  SHA512:
6
- metadata.gz: 10b8f4fb11edd3746d143456d89fa85e57cf0d46c0166ed15e6a678d240fcdc1fbafbe19a5e2c130972b66988a54ad13f1b58b00fef74ad9ee01a5a7b132ef65
7
- data.tar.gz: 02e53d5d6f47657543503afac5a5ea29de347c78a039673900a9da2e10fac7952b1d1f02c956f1e70e66a104769204207711474d556c15f3ed1470ce595af8bd
6
+ metadata.gz: 1eac7a0992c9d806a76c35cc31805bb716e7ca8b39e4b15b0609ac8c9415464c816b6b57a74821745b213ad57a9e21843f641b16663c19cf3e46d267b6216ce9
7
+ data.tar.gz: f81c9081bad5354bb6e0f056596b9c8db7ce5878d6ff6d1da5e82536c218e143c59ef60389bda4b27bed205d09881c35e6c7dccf28f8f15d7395cf487142fe00
data/.travis.yml CHANGED
@@ -1,4 +1,9 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2.1
3
+ - 2.2
4
+
4
5
  before_install: gem install bundler -v 1.11.2
6
+ script:
7
+ - gem build ztimer.gemspec
8
+ - gem install ztimer --local
9
+ - bundle exec rspec
data/Gemfile CHANGED
@@ -2,3 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in ztimer.gemspec
4
4
  gemspec
5
+
6
+ group :test do
7
+ gem 'lounger', '~> 0.2.0'
8
+ end
data/README.md CHANGED
@@ -1,7 +1,9 @@
1
1
  # Ztimer
2
2
 
3
- **Ztimer** is a Ruby gem that allows to get asynchronous delayed notifications. You can enqueue callbacks to be
4
- called after some amount of time.
3
+ **Ztimer** is a simple Ruby implementation of an asynchronous timer, that allows to enqueue the execution of Ruby
4
+ code, so that it will be asynchronously executed on timeout. It's very useful when you need a simple way to execute
5
+ some code asynchronously or with a certain delay.
6
+
5
7
 
6
8
  ## Installation
7
9
 
@@ -46,14 +48,27 @@ end
46
48
  sleep 10 # wait for 10 seconds (10 executions)
47
49
  job.cancel! # cancel the recurrent job
48
50
 
51
+ # Custom Ztimer instance
52
+ my_timer = Ztimer.new(concurrency: 5) # create a new Ztimer instance
53
+ 10.times do
54
+ # Use the custom ztimer to execute jobs asynchronously
55
+ my_timer.async do
56
+ puts "Doing async job..."
57
+ end
58
+ end
49
59
  ```
50
60
 
51
61
  By default **Ztimer** will run at maximum 20 jobs concurrently, so that if you have 100 jobs to be
52
- 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.
62
+ 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.
53
63
 
54
- 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`).
64
+ 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`).
65
+
66
+ If you're using custom **Ztimer** instance, you can specify the concurrency while creating the new instance:
67
+
68
+ ```ruby
69
+ my_timer = Ztimer.new(concurrency: 42) # create a ztimer with concurrency set to 42
70
+ ```
55
71
 
56
72
  ## Contributing
57
73
 
58
74
  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.
59
-
data/lib/ztimer.rb CHANGED
@@ -3,116 +3,124 @@ require "ztimer/slot"
3
3
  require "ztimer/sorted_store"
4
4
  require "ztimer/watcher"
5
5
 
6
- module Ztimer
7
- @concurrency = 20
8
- @watcher = Ztimer::Watcher.new(){|slot| execute(slot) }
9
- @workers_lock = Mutex.new
10
- @count_lock = Mutex.new
11
- @queue = Queue.new
12
- @running = 0
13
- @count = 0
14
-
15
- class << self
16
- attr_reader :concurrency, :running, :count, :watcher, :queue
17
-
18
- def async(&callback)
19
- enqueued_at = utc_microseconds
20
- slot = Slot.new(enqueued_at, enqueued_at, -1, &callback)
21
-
22
- incr_counter!
23
- execute(slot)
24
-
25
- return slot
26
- end
6
+ class Ztimer
7
+ @default_instance = nil
8
+
9
+ attr_reader :concurrency, :running, :count, :watcher, :queue
10
+
11
+ def initialize(concurrency: 20)
12
+ @concurrency = concurrency
13
+ @watcher = Ztimer::Watcher.new(){|slot| execute(slot) }
14
+ @workers_lock = Mutex.new
15
+ @count_lock = Mutex.new
16
+ @queue = Queue.new
17
+ @running = 0
18
+ @count = 0
19
+ end
27
20
 
28
- def after(milliseconds, &callback)
29
- enqueued_at = utc_microseconds
30
- expires_at = enqueued_at + milliseconds * 1000
31
- slot = Slot.new(enqueued_at, expires_at, -1, &callback)
21
+ def async(&callback)
22
+ enqueued_at = utc_microseconds
23
+ slot = Slot.new(enqueued_at, enqueued_at, -1, &callback)
32
24
 
33
- add(slot)
25
+ incr_counter!
26
+ execute(slot)
34
27
 
35
- return slot
36
- end
28
+ return slot
29
+ end
37
30
 
38
- def every(milliseconds, &callback)
39
- enqueued_at = utc_microseconds
40
- expires_at = enqueued_at + milliseconds * 1000
41
- slot = Slot.new(enqueued_at, expires_at, milliseconds * 1000, &callback)
31
+ def after(milliseconds, &callback)
32
+ enqueued_at = utc_microseconds
33
+ expires_at = enqueued_at + milliseconds * 1000
34
+ slot = Slot.new(enqueued_at, expires_at, -1, &callback)
42
35
 
43
- add(slot)
36
+ add(slot)
44
37
 
45
- return slot
46
- end
38
+ return slot
39
+ end
47
40
 
48
- def jobs_count
49
- return @watcher.jobs
50
- end
41
+ def every(milliseconds, &callback)
42
+ enqueued_at = utc_microseconds
43
+ expires_at = enqueued_at + milliseconds * 1000
44
+ slot = Slot.new(enqueued_at, expires_at, milliseconds * 1000, &callback)
51
45
 
52
- def concurrency=(new_value)
53
- raise ArgumentError.new("Invalid concurrency value: #{new_value}") unless new_value.is_a?(Fixnum) && new_value >= 1
54
- @concurrency = new_value
55
- end
46
+ add(slot)
56
47
 
48
+ return slot
49
+ end
57
50
 
58
- def stats
59
- {
60
- running: @running,
61
- scheduled: @watcher.jobs,
62
- executing: @queue.size,
63
- total: @count
64
- }
65
- end
51
+ def jobs_count
52
+ return @watcher.jobs
53
+ end
66
54
 
67
- protected
55
+ def concurrency=(new_value)
56
+ raise ArgumentError.new("Invalid concurrency value: #{new_value}") unless new_value.is_a?(Fixnum) && new_value >= 1
57
+ @concurrency = new_value
58
+ end
68
59
 
69
- def add(slot)
70
- incr_counter!
71
- @watcher << slot
72
- end
73
60
 
74
- def incr_counter!
75
- @count_lock.synchronize{ @count += 1 }
76
- end
61
+ def stats
62
+ {
63
+ running: @running,
64
+ scheduled: @watcher.jobs,
65
+ executing: @queue.size,
66
+ total: @count
67
+ }
68
+ end
77
69
 
78
- def execute(slot)
79
- @queue << slot
80
70
 
81
- @workers_lock.synchronize do
82
- [@concurrency - @running, @queue.size].min.times do
83
- @running += 1
84
- start_new_thread!
85
- end
71
+ def self.method_missing(name, *args, &block)
72
+ @default_instance ||= Ztimer.new(concurrency: 20)
73
+ @default_instance.send(name, *args, &block)
74
+ end
75
+
76
+ protected
77
+
78
+ def add(slot)
79
+ incr_counter!
80
+ @watcher << slot
81
+ end
82
+
83
+ def incr_counter!
84
+ @count_lock.synchronize{ @count += 1 }
85
+ end
86
+
87
+ def execute(slot)
88
+ @queue << slot
89
+
90
+ @workers_lock.synchronize do
91
+ [@concurrency - @running, @queue.size].min.times do
92
+ @running += 1
93
+ start_new_thread!
86
94
  end
87
95
  end
96
+ end
88
97
 
89
- def start_new_thread!
90
- worker = Thread.new do
91
- begin
92
- loop do
93
- current_slot = nil
94
- @workers_lock.synchronize do
95
- current_slot = @queue.pop(true) unless @queue.empty?
96
- end
97
- break if current_slot.nil?
98
-
99
- begin
100
- current_slot.executed_at = utc_microseconds
101
- current_slot.callback.call(current_slot) unless current_slot.callback.nil? || current_slot.canceled?
102
- rescue => e
103
- STDERR.puts e.inspect + (e.backtrace ? "\n" + e.backtrace.join("\n") : "")
104
- end
98
+ def start_new_thread!
99
+ worker = Thread.new do
100
+ begin
101
+ loop do
102
+ current_slot = nil
103
+ @workers_lock.synchronize do
104
+ current_slot = @queue.pop(true) unless @queue.empty?
105
+ end
106
+ break if current_slot.nil?
107
+
108
+ begin
109
+ current_slot.executed_at = utc_microseconds
110
+ current_slot.callback.call(current_slot) unless current_slot.callback.nil? || current_slot.canceled?
111
+ rescue => e
112
+ STDERR.puts e.inspect + (e.backtrace ? "\n" + e.backtrace.join("\n") : "")
105
113
  end
106
- rescue ThreadError
107
- puts "queue is empty"
108
114
  end
109
- @workers_lock.synchronize { @running -= 1 }
115
+ rescue ThreadError
116
+ puts "queue is empty"
110
117
  end
111
- worker.abort_on_exception = true
118
+ @workers_lock.synchronize { @running -= 1 }
112
119
  end
120
+ worker.abort_on_exception = true
121
+ end
113
122
 
114
- def utc_microseconds
115
- return Time.now.to_f * 1_000_000
116
- end
123
+ def utc_microseconds
124
+ return Time.now.to_f * 1_000_000
117
125
  end
118
- end
126
+ end
data/lib/ztimer/slot.rb CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- module Ztimer
2
+ class Ztimer
3
3
  class Slot
4
4
  attr_reader :enqueued_at, :expires_at, :recurrency, :callback
5
5
  attr_accessor :started_at, :executed_at
@@ -36,4 +36,4 @@ module Ztimer
36
36
  return @expires_at <=> other.expires_at
37
37
  end
38
38
  end
39
- end
39
+ end
@@ -1,5 +1,5 @@
1
1
 
2
- module Ztimer
2
+ class Ztimer
3
3
  class SortedStore
4
4
 
5
5
  def initialize
@@ -94,4 +94,4 @@ module Ztimer
94
94
  end
95
95
  end
96
96
  end
97
- end
97
+ end
@@ -1,3 +1,3 @@
1
- module Ztimer
2
- VERSION = "0.5.0"
1
+ class Ztimer
2
+ VERSION = "0.6.0"
3
3
  end
@@ -1,5 +1,5 @@
1
1
 
2
- module Ztimer
2
+ class Ztimer
3
3
  class Watcher
4
4
 
5
5
  def initialize(&callback)
@@ -92,4 +92,4 @@ module Ztimer
92
92
  return Time.now.to_f * 1_000_000
93
93
  end
94
94
  end
95
- end
95
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ztimer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Groza Sergiu
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-10-14 00:00:00.000000000 Z
11
+ date: 2017-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -100,4 +100,3 @@ signing_key:
100
100
  specification_version: 4
101
101
  summary: An asyncrhonous timer
102
102
  test_files: []
103
- has_rdoc: