timed_semaphore 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6356f0e509d4d66d0fe37b7d83e498a7a5c02438
4
+ data.tar.gz: a4cbfb7255933034f2b97cd3e4d5b1a936519b8d
5
+ SHA512:
6
+ metadata.gz: 4520d9f271ade92caec7970c63fa052e38153fe34caacb47898b5a81aabed74b8fa45060e11c9e54ec038c7e9b8e54a62bd23a045a0ff2386fda4eefaf7980ee
7
+ data.tar.gz: 1d11602b416694c51f45d88291373699793d7543bfbd43c0ee75a1e2dbd154521c0a08ec1cec9a3068be53850b0ff5066485101d85df3fe1a33b9c66668b8830
@@ -0,0 +1,45 @@
1
+ class TimedSemaphore
2
+ def initialize(num_of_ops, num_of_seconds)
3
+ @count = 0
4
+ @limit = num_of_ops
5
+ @period = num_of_seconds
6
+ @lock = Monitor.new
7
+ @condition = @lock.new_cond
8
+ @timer = nil
9
+ end
10
+
11
+ # Acquires a permit or sleeps the thread if all permits are exhausted
12
+ def acquire
13
+ synchronize do
14
+ @condition.wait while @limit > 0 && @count == @limit
15
+ @count += 1
16
+ start_timer if @timer.nil?
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ # Starts a thread which releases all permits after @period seconds
23
+ def start_timer
24
+ synchronize do
25
+ @timer = Thread.new do
26
+ sleep(@period)
27
+ release_permits
28
+ end
29
+ end
30
+ end
31
+
32
+ # Releases all permits and notifies all waiting threads to try acquire again
33
+ def release_permits
34
+ synchronize do
35
+ @timer = nil
36
+ @count = 0
37
+ @condition.broadcast
38
+ end
39
+ end
40
+
41
+ def synchronize(&block)
42
+ fail 'No block given' unless block_given?
43
+ @lock.synchronize(&block)
44
+ end
45
+ end
@@ -0,0 +1,42 @@
1
+ require 'minitest/autorun'
2
+ require 'timed_semaphore'
3
+
4
+ class TimedSemaphoreTest < Minitest::Test
5
+ def test_successful_acquire
6
+ semaphore = TimedSemaphore.new(1, 10)
7
+ t = create_waiting_thread(semaphore)
8
+ assert_equal 'run', t.status
9
+ assert_equal 'finished', t.value
10
+ end
11
+
12
+ def test_exhausted_permits
13
+ semaphore = TimedSemaphore.new(1, 10)
14
+ threads = []
15
+ 5.times { threads << create_waiting_thread(semaphore) }
16
+ sleep(0.01)
17
+ count_sleeping = threads.count { |t| t.status == 'sleep' }
18
+ assert_equal 4, count_sleeping
19
+ end
20
+
21
+ def test_releasing_permits
22
+ semaphore = TimedSemaphore.new(1, 2)
23
+ t = create_waiting_thread(semaphore)
24
+ sleep(0.01)
25
+ assert_equal false, t.status
26
+ t = create_waiting_thread(semaphore)
27
+ sleep(0.01)
28
+ assert_equal 'sleep', t.status
29
+ sleep(2)
30
+ assert_equal false, t.status
31
+ assert_equal 'finished', t.value
32
+ end
33
+
34
+ private
35
+
36
+ def create_waiting_thread(semaphore)
37
+ Thread.new do
38
+ semaphore.acquire
39
+ 'finished'
40
+ end
41
+ end
42
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: timed_semaphore
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sadžid Suljić
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-06-10 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A TimedSemaphore is a specialized implementation of a Semaphore that
14
+ gives a number of permits in a given time frame
15
+ email: sadzid.suljic@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/timed_semaphore.rb
21
+ - test/timed_semaphore_test.rb
22
+ homepage: https://github.com/ssuljic/timed_semaphore
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.4.6
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: Implementation of TimedSemaphore
46
+ test_files:
47
+ - test/timed_semaphore_test.rb