throttler 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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