throttler 0.1.4 → 0.2.0

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.
data/README.md CHANGED
@@ -10,7 +10,7 @@ Throttle concurrency.
10
10
 
11
11
  def request
12
12
  throttle("foo#{interface}", 1.0) do
13
- #noop
13
+ # do something
14
14
  end
15
15
  end
16
16
 
@@ -27,7 +27,7 @@ Throttle concurrency.
27
27
  end
28
28
 
29
29
  sleep 1.2
30
- count.should eql 2 # 98 threads pending
30
+ count.should eql(2)
31
31
 
32
32
  Use case
33
33
  --------
@@ -1,26 +1,22 @@
1
1
  module Throttler
2
-
3
- # The Throttle file
4
- class Throttle
2
+ class Timer
5
3
  def initialize(name)
6
4
  path = "/tmp/.#{name}"
7
5
  @file = File.open(path, File::RDWR|File::CREAT)
8
6
  end
9
7
 
10
- def delay(interval)
11
- last = @file.gets.to_f
12
- last = (Time.now.to_f - interval) if last == 0.0
13
-
14
- sleep [last + interval - Time.now.to_f, 0.0].max
15
- end
16
-
17
8
  def lock
18
9
  @file.flock(File::LOCK_EX)
19
10
  end
20
11
 
21
12
  def timestamp
13
+ @timestamp ||= @file.gets.to_f
14
+ end
15
+
16
+ def timestamp=(time)
22
17
  @file.rewind
23
- @file.write(Time.now.to_f)
18
+ @file.write(time)
19
+ @timestamp = time
24
20
  end
25
21
 
26
22
  def unlock
data/lib/throttler.rb CHANGED
@@ -1,26 +1,26 @@
1
- require File.dirname(__FILE__) + "/throttler/throttle"
1
+ require File.dirname(__FILE__) + "/throttler/timer"
2
2
 
3
3
  # The Throttler module.
4
4
  #
5
- # Simply include this in the class where you wish to use the throttler.
5
+ # Include this in the class where you wish to use the throttler.
6
6
  module Throttler
7
7
 
8
- # Throttles execution of a block of code.
8
+ # Throttles the frequency in which a block is run.
9
9
  #
10
10
  # Pass name of throttler and optionally, the interval between each
11
- # moment of execution. Latte defaults to one second.
11
+ # moment of execution. Latter defaults to one second.
12
12
  #
13
13
  # throttle("foo") { some_code }
14
14
  #
15
15
  def throttle(name, interval=1.0)
16
+ timer = Timer.new(name)
17
+ timer.lock
16
18
  begin
17
- file = Throttle.new(name)
18
- file.lock
19
- file.delay interval
19
+ sleep [timer.timestamp + interval - Time.now.to_f, 0.0].max
20
20
  yield if block_given?
21
- file.timestamp
21
+ timer.timestamp = Time.now.to_f
22
22
  ensure
23
- file.unlock
23
+ timer.unlock
24
24
  end
25
25
  end
26
26
  end
@@ -20,7 +20,7 @@ class Bar
20
20
  def noop; end
21
21
  end
22
22
 
23
- describe "Simple integration tests" do
23
+ describe "Throttler" do
24
24
  before do
25
25
  FileUtils.rm "/tmp/.bar", :force => true
26
26
  FileUtils.rm "/tmp/.baz", :force => true
@@ -0,0 +1,56 @@
1
+ require "spec_helper"
2
+ require "benchmark"
3
+ require "fileutils"
4
+
5
+ module Throttler
6
+ describe Timer do
7
+ before do
8
+ FileUtils.rm "/tmp/.foo", :force => true
9
+ @timer = Timer.new("foo")
10
+ end
11
+
12
+ it "creates a file" do
13
+ File.exists?("/tmp/.foo").should be_true
14
+ end
15
+
16
+ context "#lock" do
17
+ it "locks the file" do
18
+ @timer.lock
19
+ File.open("/tmp/.foo") { |f| f.flock(File::LOCK_EX | File::LOCK_NB).should be_false }
20
+ end
21
+ end
22
+
23
+ context "#timestamp" do
24
+ it "gets the timestamp" do
25
+ now = Time.now.to_f
26
+ File.open("/tmp/.foo", "w") { |f| f.write(now) }
27
+ @timer.timestamp.should be_close(now, 0.1)
28
+ end
29
+
30
+ it "returns 0.0 when file is first created" do
31
+ @timer.timestamp.should eql(0.0)
32
+ end
33
+ end
34
+
35
+ context "#timestamp=" do
36
+ it "sets the timestamp" do
37
+ now = Time.now.to_f
38
+ @timer.timestamp= now
39
+
40
+ # We need to close the file first
41
+ @timer.instance_variable_get(:@file).close
42
+
43
+ File.open("/tmp/.foo") { |f| f.gets.to_f.should be_close(now, 0.1) }
44
+ end
45
+ end
46
+
47
+ context "#unlock" do
48
+ it "unlocks the file" do
49
+ @timer.lock
50
+ @timer.unlock
51
+
52
+ File.open("/tmp/.foo") { |f| f.flock(File::LOCK_EX | File::LOCK_NB).should_not be_false }
53
+ end
54
+ end
55
+ end
56
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 4
9
- version: 0.1.4
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Hakan Ensari
@@ -15,11 +15,11 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-07-24 00:00:00 +01:00
18
+ date: 2010-07-26 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
22
- description: Throttles the frequency at which concurrently-running Ruby blocks are executed.
22
+ description: Throttles the frequency in which asynchronously-executed Ruby blocks are run on a single server or network interface.
23
23
  email: code@papercavalier.com
24
24
  executables: []
25
25
 
@@ -31,12 +31,12 @@ extra_rdoc_files:
31
31
  files:
32
32
  - LICENSE
33
33
  - lib/throttler.rb
34
- - lib/throttler/throttle.rb
34
+ - lib/throttler/timer.rb
35
35
  - README.md
36
36
  - spec/fixtures/foo.rb
37
- - spec/integration/scenarios_spec.rb
37
+ - spec/integration/throttler_spec.rb
38
38
  - spec/spec_helper.rb
39
- - spec/unit/throttler/throttle_spec.rb
39
+ - spec/unit/throttler/timer_spec.rb
40
40
  - spec/unit/throttler_spec.rb
41
41
  has_rdoc: true
42
42
  homepage: http://github.com/papercavalier/throttler
@@ -52,7 +52,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - ">="
54
54
  - !ruby/object:Gem::Version
55
- hash: -2072448878210444692
55
+ hash: 4404238439013896602
56
56
  segments:
57
57
  - 0
58
58
  version: "0"
@@ -70,10 +70,10 @@ rubyforge_project:
70
70
  rubygems_version: 1.3.7
71
71
  signing_key:
72
72
  specification_version: 3
73
- summary: Throttles the frequency at which concurrently-running Ruby blocks are executed.
73
+ summary: Throttles the frequency in which asynchronously-executed Ruby blocks are run on a single server or network interface.
74
74
  test_files:
75
75
  - spec/fixtures/foo.rb
76
- - spec/integration/scenarios_spec.rb
76
+ - spec/integration/throttler_spec.rb
77
77
  - spec/spec_helper.rb
78
- - spec/unit/throttler/throttle_spec.rb
78
+ - spec/unit/throttler/timer_spec.rb
79
79
  - spec/unit/throttler_spec.rb
@@ -1,66 +0,0 @@
1
- require "spec_helper"
2
- require "benchmark"
3
- require "fileutils"
4
-
5
- module Throttler
6
- describe Throttle do
7
- before do
8
- FileUtils.rm "/tmp/.foo", :force => true
9
- @foo = Throttle.new("foo")
10
- end
11
-
12
- it "creates a file" do
13
- File.exists?("/tmp/.foo").should be_true
14
- end
15
-
16
- context "#lock" do
17
- it "locks the file" do
18
- @foo.lock
19
- File.open("/tmp/.foo") { |f| f.flock(File::LOCK_EX | File::LOCK_NB).should be_false }
20
- end
21
- end
22
-
23
- context "#delay" do
24
- it "throttles if file contains a timestamp" do
25
- file = @foo.instance_variable_get(:@file)
26
- file.stub!(:gets).and_return(Time.now.to_f)
27
-
28
- time = Benchmark.realtime do
29
- @foo.delay(1.0)
30
- end
31
-
32
- time.should be_close 1, 0.1
33
- end
34
-
35
- it "does not throttle if file is blank" do
36
- file = @foo.instance_variable_get(:@file)
37
- file.stub!(:gets).and_return("")
38
-
39
- time = Benchmark.realtime do
40
- @foo.delay(1.0)
41
- end
42
-
43
- time.should be_close 0, 0.1
44
- end
45
- end
46
-
47
- context "#timestamp" do
48
- it "timestamps file" do
49
- @foo.timestamp
50
- file = @foo.instance_variable_get(:@file)
51
- file.close # We need to close the file first
52
-
53
- File.open("/tmp/.foo") { |f| f.gets.to_f.should be_close Time.now.to_f, 0.1 }
54
- end
55
- end
56
-
57
- context "#unlock" do
58
- it "unlocks the file" do
59
- @foo.lock
60
- @foo.unlock
61
-
62
- File.open("/tmp/.foo") { |f| f.flock(File::LOCK_EX | File::LOCK_NB).should_not be_false }
63
- end
64
- end
65
- end
66
- end