electric_slide 0.0.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1 +1,41 @@
1
1
  require 'spec_helper'
2
+
3
+ describe ElectricSlide do
4
+ context "creating a queue" do
5
+ after :each do
6
+ ElectricSlide.shutdown_queue :fake
7
+ end
8
+
9
+ let(:queue_class) { double :fake_queue_class }
10
+ let(:queue_inst) { double :fake_queue_instance }
11
+
12
+ it "should default to an ElectricSlide::CallQueue if one is not specified" do
13
+ ElectricSlide.create :fake
14
+ expect { ElectricSlide.get_queue :fake }.to_not raise_error
15
+ end
16
+
17
+ it "should start the queue upon registration" do
18
+ expect(queue_class).to receive(:work).once.and_return queue_inst
19
+ expect(queue_inst).to receive(:terminate).once
20
+ ElectricSlide.create :fake, queue_class
21
+ end
22
+
23
+ it "should preserve additional queue arguments" do
24
+ queue = double(:fake_queue)
25
+ expect(queue_class).to receive(:work).with(:foo, :bar, :baz).once.and_return queue_inst
26
+ expect(queue_inst).to receive(:terminate).once
27
+ ElectricSlide.create :fake, queue_class, :foo, :bar, :baz
28
+ end
29
+
30
+ it "should not allow a second queue to be created with the same name" do
31
+ ElectricSlide.create :fake
32
+ expect { ElectricSlide.create :fake }.to raise_error
33
+ end
34
+ end
35
+
36
+ it "should raise if attempting to work with a queue that doesn't exist" do
37
+ expect { ElectricSlide.get_queue!("does not exist!") }.to raise_error
38
+ expect { ElectricSlide.shutdown_queue("does not exist!") }.to raise_error
39
+ end
40
+
41
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,25 +1,18 @@
1
1
  $:.push File.join(File.dirname(__FILE__), '..', 'lib')
2
2
  Thread.abort_on_exception = true
3
3
 
4
- %w{
4
+ %w(
5
5
  adhearsion
6
6
  electric_slide
7
- electric_slide/queued_call
8
- electric_slide/queue_strategy
9
- electric_slide/round_robin
10
7
  rspec/core
11
- flexmock
12
- flexmock/rspec
13
- }.each { |r| require r }
8
+ ).each { |r| require r }
14
9
 
15
10
  RSpec.configure do |config|
16
- config.mock_framework = :flexmock
17
- config.filter_run :focus => true
11
+ config.filter_run focus: true
18
12
  config.run_all_when_everything_filtered = true
19
- config.color_enabled = true
20
13
  end
21
14
 
22
15
  def dummy_call
23
- Object.new
16
+ Adhearsion::Call.new
24
17
  end
25
18
 
metadata CHANGED
@@ -1,125 +1,139 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: electric_slide
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Klang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-10 00:00:00.000000000 Z
11
+ date: 2015-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: adhearsion
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: countdownlatch
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: 2.5.0
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: 2.5.0
69
69
  - !ruby/object:Gem::Dependency
70
- name: flexmock
70
+ name: ci_reporter
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: 0.9.0
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: 0.9.0
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: ci_reporter
84
+ name: guard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: guard-rspec
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - '>='
101
+ - - ">="
88
102
  - !ruby/object:Gem::Version
89
103
  version: '0'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - '>='
108
+ - - ">="
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: simplecov
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
- - - '>='
115
+ - - ">="
102
116
  - !ruby/object:Gem::Version
103
117
  version: '0'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
- - - '>='
122
+ - - ">="
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: simplecov-rcov
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
- - - '>='
129
+ - - ">="
116
130
  - !ruby/object:Gem::Version
117
131
  version: '0'
118
132
  type: :development
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
- - - '>='
136
+ - - ">="
123
137
  - !ruby/object:Gem::Version
124
138
  version: '0'
125
139
  description: Automatic Call Distributor (ACD) for Adhearsion. Currently implements
@@ -129,21 +143,25 @@ executables: []
129
143
  extensions: []
130
144
  extra_rdoc_files: []
131
145
  files:
132
- - .gitignore
146
+ - ".gitignore"
147
+ - ".rspec"
133
148
  - Gemfile
149
+ - Guardfile
134
150
  - LICENSE
135
151
  - README.markdown
136
152
  - Rakefile
137
153
  - config/ahn_acd.yml
138
154
  - electric_slide.gemspec
139
155
  - lib/electric_slide.rb
140
- - lib/electric_slide/queue_strategy.rb
141
- - lib/electric_slide/queued_call.rb
142
- - lib/electric_slide/round_robin.rb
143
- - lib/electric_slide/round_robin_meetme.rb
144
- - spec/electric_slide/queue_strategy_spec.rb
145
- - spec/electric_slide/queued_call_spec.rb
146
- - spec/electric_slide/round_robin_spec.rb
156
+ - lib/electric_slide/agent.rb
157
+ - lib/electric_slide/agent_strategy/fixed_priority.rb
158
+ - lib/electric_slide/agent_strategy/longest_idle.rb
159
+ - lib/electric_slide/call_queue.rb
160
+ - lib/electric_slide/plugin.rb
161
+ - lib/electric_slide/version.rb
162
+ - spec/electric_slide/agent_spec.rb
163
+ - spec/electric_slide/agent_strategy/fixed_priority_spec.rb
164
+ - spec/electric_slide/call_queue_spec.rb
147
165
  - spec/electric_slide_spec.rb
148
166
  - spec/spec_helper.rb
149
167
  homepage: http://github.com/adhearsion/electric_slide
@@ -155,19 +173,18 @@ require_paths:
155
173
  - lib
156
174
  required_ruby_version: !ruby/object:Gem::Requirement
157
175
  requirements:
158
- - - '>='
176
+ - - ">="
159
177
  - !ruby/object:Gem::Version
160
178
  version: '0'
161
179
  required_rubygems_version: !ruby/object:Gem::Requirement
162
180
  requirements:
163
- - - '>='
181
+ - - ">="
164
182
  - !ruby/object:Gem::Version
165
183
  version: '0'
166
184
  requirements: []
167
185
  rubyforge_project:
168
- rubygems_version: 2.0.3
186
+ rubygems_version: 2.4.5
169
187
  signing_key:
170
188
  specification_version: 2
171
189
  summary: Automatic Call Distributor for Adhearsion
172
190
  test_files: []
173
- has_rdoc: true
@@ -1,18 +0,0 @@
1
- class ElectricSlide
2
- module QueueStrategy
3
- def wrap_call(call)
4
- call = QueuedCall.new(call) unless call.respond_to?(:queued_time)
5
- call
6
- end
7
-
8
- def priority_enqueue(call)
9
- # TODO: Add this call to the front of the line
10
- enqueue call
11
- end
12
-
13
- def enqueue(call)
14
- call.hold
15
- end
16
- end
17
- end
18
-
@@ -1,24 +0,0 @@
1
- require 'countdownlatch'
2
-
3
- class ElectricSlide
4
- class QueuedCall
5
- attr_accessor :call, :queued_time
6
-
7
- def initialize(call)
8
- @call = call
9
- @queued_time = Time.now
10
- end
11
-
12
- def hold
13
- call.execute 'StartMusicOnHold'
14
- @latch = CountDownLatch.new 1
15
- @latch.wait
16
- call.execute 'StopMusicOnHold'
17
- end
18
-
19
- def make_ready!
20
- @latch.countdown!
21
- end
22
- end
23
- end
24
-
@@ -1,46 +0,0 @@
1
- require 'thread'
2
- require 'electric_slide/queue_strategy'
3
-
4
- class ElectricSlide
5
- class RoundRobin
6
- include QueueStrategy
7
- attr_reader :queue
8
-
9
- def initialize
10
- @queue = []
11
- @agents_waiting = []
12
- @conditional = ConditionVariable.new
13
- end
14
-
15
- def next_call
16
- call = nil
17
- synchronize do
18
- @agents_waiting << Thread.current
19
- @conditional.wait(@mutex) if @queue.length == 0
20
- @agents_waiting.delete Thread.current
21
- call = @queue.shift
22
- end
23
-
24
- call.make_ready!
25
- call
26
- end
27
-
28
- def agents_waiting
29
- synchronize do
30
- @agents_waiting.dup
31
- end
32
- end
33
-
34
- # TODO: Add mechanism to add calls with higher priority to the front of the queue.
35
-
36
- def enqueue(call)
37
- call = wrap_call(call)
38
- synchronize do
39
- @queue << call
40
- @conditional.signal if @queue.length == 1
41
- end
42
- super
43
- end
44
- end
45
- end
46
-
@@ -1,34 +0,0 @@
1
- class ElectricSlide
2
- class RoundRobinMeetme
3
- include QueueStrategy
4
-
5
- def initialize(call)
6
- @queue = []
7
- end
8
-
9
- def next_call
10
- call = synchronize do
11
- @queue.pop
12
- end
13
-
14
- call.make_ready!
15
- call
16
- end
17
-
18
- def priority_enqueue(call)
19
- call = wrap_call(call)
20
-
21
- synchronize do
22
- @queue.unshift call
23
- end
24
- super
25
- end
26
-
27
- def enqueue(call)
28
- synchronize do
29
- @queue << call
30
- end
31
- end
32
- end
33
- end
34
-
@@ -1,16 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ElectricSlide::QueueStrategy do
4
- include ElectricSlide::QueueStrategy
5
-
6
- describe '#wrap_call' do
7
- it 'should pass through a QueuedCall object' do
8
- obj = ElectricSlide::QueuedCall.new dummy_call
9
- wrap_call(obj).should be obj
10
- end
11
-
12
- it 'should wrap any object that does not respond to #queued_time' do
13
- wrap_call(dummy_call).should be_a ElectricSlide::QueuedCall
14
- end
15
- end
16
- end
@@ -1,42 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ElectricSlide::QueuedCall do
4
- it 'should initialize the queued_time to the current time' do
5
- now = Time.now
6
- flexmock(Time).should_receive(:now).once.and_return now
7
- qcall = ElectricSlide::QueuedCall.new dummy_call
8
- qcall.instance_variable_get(:@queued_time).should == now
9
- end
10
-
11
- it 'should start and stop music on hold when put on hold and released' do
12
- # Both tests are combined here so we do not leave too many suspended threads lying about
13
- queued_caller = dummy_call
14
- flexmock(queued_caller).should_receive(:execute).once.with('StartMusicOnHold')
15
- flexmock(queued_caller).should_receive(:execute).once.with('StopMusicOnHold')
16
- qcall = ElectricSlide::QueuedCall.new queued_caller
17
-
18
- # Place the call on hold and wait for it to enqueue
19
- Thread.new { qcall.hold }
20
- sleep 0.5
21
-
22
- # Release the call from being on hold and sleep to ensure we get the Stop MOH signal
23
- qcall.make_ready!
24
- sleep 0.5
25
- end
26
-
27
- it 'should block the call when put on hold' do
28
- queued_caller = dummy_call
29
- flexmock(queued_caller).should_receive(:execute).once.with('StartMusicOnHold')
30
- flexmock(queued_caller).should_receive(:execute).once.with('StopMusicOnHold')
31
- qcall = ElectricSlide::QueuedCall.new queued_caller
32
-
33
- hold_thread = Thread.new { qcall.hold }
34
-
35
- # Give the holding thread a chance to block...
36
- sleep 0.5
37
- hold_thread.status.should == "sleep"
38
- qcall.make_ready!
39
- sleep 0.5
40
- hold_thread.status.should be false
41
- end
42
- end