tickr_client 0.0.1 → 1.0.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/Gemfile +2 -0
- data/Gemfile.lock +24 -0
- data/README.md +36 -4
- data/VERSION +1 -1
- data/lib/tickr/interfaces/active_record.rb +22 -0
- data/lib/tickr_client.rb +1 -1
- data/spec/lib/tickr/interfaces/active_record_spec.rb +43 -0
- data/spec/spec_helper.rb +12 -1
- data/spec/tickr_client_spec.rb +5 -5
- data/tickr_client.gemspec +75 -0
- metadata +38 -3
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,16 +1,36 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
+
activemodel (4.0.0)
|
5
|
+
activesupport (= 4.0.0)
|
6
|
+
builder (~> 3.1.0)
|
7
|
+
activerecord (4.0.0)
|
8
|
+
activemodel (= 4.0.0)
|
9
|
+
activerecord-deprecated_finders (~> 1.0.2)
|
10
|
+
activesupport (= 4.0.0)
|
11
|
+
arel (~> 4.0.0)
|
12
|
+
activerecord-deprecated_finders (1.0.3)
|
13
|
+
activesupport (4.0.0)
|
14
|
+
i18n (~> 0.6, >= 0.6.4)
|
15
|
+
minitest (~> 4.2)
|
16
|
+
multi_json (~> 1.3)
|
17
|
+
thread_safe (~> 0.1)
|
18
|
+
tzinfo (~> 0.3.37)
|
19
|
+
arel (4.0.0)
|
4
20
|
atomic (1.1.10)
|
21
|
+
builder (3.1.4)
|
5
22
|
diff-lcs (1.2.4)
|
6
23
|
fakeweb (1.3.0)
|
7
24
|
git (1.2.5)
|
25
|
+
i18n (0.6.4)
|
8
26
|
jeweler (1.8.4)
|
9
27
|
bundler (~> 1.0)
|
10
28
|
git (>= 1.2.5)
|
11
29
|
rake
|
12
30
|
rdoc
|
13
31
|
json (1.8.0)
|
32
|
+
minitest (4.7.5)
|
33
|
+
multi_json (1.7.7)
|
14
34
|
rake (10.1.0)
|
15
35
|
rdoc (4.0.1)
|
16
36
|
json (~> 1.4)
|
@@ -22,16 +42,20 @@ GEM
|
|
22
42
|
rspec-expectations (2.13.0)
|
23
43
|
diff-lcs (>= 1.1.3, < 2.0)
|
24
44
|
rspec-mocks (2.13.1)
|
45
|
+
sqlite3 (1.3.7)
|
25
46
|
thread_safe (0.1.0)
|
26
47
|
atomic
|
48
|
+
tzinfo (0.3.37)
|
27
49
|
|
28
50
|
PLATFORMS
|
29
51
|
ruby
|
30
52
|
|
31
53
|
DEPENDENCIES
|
54
|
+
activerecord (>= 2.3.0)
|
32
55
|
bundler (~> 1.2)
|
33
56
|
fakeweb (~> 1.3)
|
34
57
|
jeweler (~> 1.8)
|
35
58
|
json (~> 1.8)
|
36
59
|
rspec (~> 2.13)
|
60
|
+
sqlite3 (~> 1.3)
|
37
61
|
thread_safe (~> 0.1)
|
data/README.md
CHANGED
@@ -4,11 +4,15 @@ tickr_client is a Ruby library for talking to a [tickr ticketing server](http://
|
|
4
4
|
|
5
5
|
## Getting Started
|
6
6
|
|
7
|
-
It is recommended that you create a global instance of tickr_client and call it
|
7
|
+
It is recommended that you create a global instance of tickr_client and call it
|
8
|
+
directly. TickrClients are threadsafe and the `#get_ticket` method may be
|
9
|
+
called safely on a single instance from all of your request handlers and
|
10
|
+
workers.
|
8
11
|
|
9
|
-
Note that the threadsafe guarantee for a ticket is only its uniqueness; tickr
|
12
|
+
Note that the threadsafe guarantee for a ticket is only its uniqueness; tickr
|
13
|
+
makes no guarantee about sequentiality.
|
10
14
|
|
11
|
-
$
|
15
|
+
$tickr = TickrClient.new(
|
12
16
|
servers: [
|
13
17
|
{host: '192.168.1.1', port: 8080},
|
14
18
|
{host: '192.168.1.2', port: 8080},
|
@@ -19,9 +23,37 @@ Note that the threadsafe guarantee for a ticket is only its uniqueness; tickr ma
|
|
19
23
|
replenish_cache_at: 10, # Load 90 more tickets when we get down to 10.
|
20
24
|
)
|
21
25
|
|
22
|
-
new_id = $
|
26
|
+
new_id = $tickr.get_ticket
|
23
27
|
|
28
|
+
## Using with ActiveRecord
|
24
29
|
|
30
|
+
To use tickr with ActiveRecord, set up an initializer as outlined above. The
|
31
|
+
ActiveRecord interface requires your tickr instance to be a global variable
|
32
|
+
named `$tickr`. This is not presently configurable (though we'd love for you
|
33
|
+
to make it so!).
|
34
|
+
|
35
|
+
All you need to do to add ActiveRecord support to your ActiveRecord models is
|
36
|
+
require our interface library and include our mixin, e.g.:
|
37
|
+
|
38
|
+
require 'tickr/interfaces/active_record' # not required with gem by default
|
39
|
+
|
40
|
+
class Person < ActiveRecord::Base
|
41
|
+
include Tickr::Interfaces::ActiveRecord
|
42
|
+
|
43
|
+
# …your code here
|
44
|
+
end
|
45
|
+
|
46
|
+
Voila! Whenever you save a new object, its ID will be set via tickr and passed
|
47
|
+
to your DBMS during its insert operation. If for any reason the ID is not set
|
48
|
+
upon row insertion, Tickr will raise a `TickrIdNotSetError` exception so that
|
49
|
+
no data is saved that might compromise referential integrity. If you wish to
|
50
|
+
fall back to an auto_increment or some other DBMS-backed scheme, you should
|
51
|
+
catch this exception.
|
52
|
+
|
53
|
+
Note that MySQL happily accepts a specific ID without requiring removal of the
|
54
|
+
AUTO_INCREMENT property on a primary key. If you use a different DBMS, please be
|
55
|
+
sure its behavior is similarly compatible or update your database table schemas
|
56
|
+
accordingly.
|
25
57
|
|
26
58
|
## Contributing to tickr_client
|
27
59
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
1.0.0
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
class TickrIdNotSetError < StandardError; end
|
4
|
+
|
5
|
+
module Tickr
|
6
|
+
module Interfaces
|
7
|
+
module ActiveRecord
|
8
|
+
def self.included(base)
|
9
|
+
base.before_create :set_tickr_id
|
10
|
+
base.before_create :ensure_id_set
|
11
|
+
|
12
|
+
private
|
13
|
+
def set_tickr_id
|
14
|
+
self.id ||= $tickr.get_ticket
|
15
|
+
end
|
16
|
+
def ensure_id_set
|
17
|
+
raise TickrIdNotSetError if self.id.nil?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/tickr_client.rb
CHANGED
@@ -70,7 +70,7 @@ class TickrClient
|
|
70
70
|
# 2. Second element of ticket group is the increment between consecutive tickets.
|
71
71
|
# 3. Third element of ticket group is the number of tickets to create.
|
72
72
|
def create_tickets_from_ticket_group(group)
|
73
|
-
initial_ticket, diff, num_of_tickets = group
|
73
|
+
initial_ticket, diff, num_of_tickets = group['first'], group['increment'], group['count']
|
74
74
|
new_tickets = [initial_ticket]
|
75
75
|
|
76
76
|
(num_of_tickets - 1).times do
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'lib', 'tickr', 'interfaces', 'active_record')
|
4
|
+
|
5
|
+
require 'active_record'
|
6
|
+
|
7
|
+
describe Tickr::Interfaces::ActiveRecord do
|
8
|
+
before do
|
9
|
+
TickrClient.any_instance.stub :fetch_tickets
|
10
|
+
$tickr = TickrClient.new({servers: [{}]})
|
11
|
+
|
12
|
+
ActiveRecord::Base.establish_connection adapter: :sqlite3, database: ':memory:'
|
13
|
+
with_silenced_output do
|
14
|
+
ActiveRecord::Schema.define do
|
15
|
+
create_table 'test_models' do |t|
|
16
|
+
t.datetime 'created_at'
|
17
|
+
t.datetime 'updated_at'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class TestModel < ActiveRecord::Base
|
23
|
+
include Tickr::Interfaces::ActiveRecord
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'parent accepts ID in place of an autoincrement value' do
|
28
|
+
# Hard-set some nonincremental IDs.
|
29
|
+
(TestModel.create! id: 1).id.should == 1
|
30
|
+
(TestModel.create! id: 6).id.should == 6
|
31
|
+
end
|
32
|
+
it 'parent creates ID from tickr' do
|
33
|
+
$tickr.stub(:get_ticket).and_return(115010)
|
34
|
+
TestModel.create!.id.should == 115010
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'raises an exception if we save a record with no ID' do
|
38
|
+
obj = TestModel.new
|
39
|
+
obj.id.should be_nil
|
40
|
+
$tickr.stub(:get_ticket).and_return(nil)
|
41
|
+
lambda{obj.save!}.should raise_error(TickrIdNotSetError)
|
42
|
+
end
|
43
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -11,10 +11,21 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
|
11
11
|
|
12
12
|
RSpec.configure do |config|
|
13
13
|
config.before(:all) do
|
14
|
-
|
14
|
+
# Allow real HTTP connections only to our local tickr server
|
15
|
+
FakeWeb.allow_net_connect = %r[^https?://localhost]
|
15
16
|
end
|
16
17
|
|
17
18
|
config.before(:each) do
|
18
19
|
FakeWeb.clean_registry
|
19
20
|
end
|
20
21
|
end
|
22
|
+
|
23
|
+
def with_silenced_output
|
24
|
+
orig_stderr = $stderr
|
25
|
+
orig_stdout = $stdout
|
26
|
+
$stderr = File.new('/dev/null', 'w')
|
27
|
+
$stdout = File.new('/dev/null', 'w')
|
28
|
+
yield
|
29
|
+
$stderr = orig_stderr
|
30
|
+
$stdout = orig_stdout
|
31
|
+
end
|
data/spec/tickr_client_spec.rb
CHANGED
@@ -69,7 +69,7 @@ describe TickrClient do
|
|
69
69
|
describe 'private instance methods' do
|
70
70
|
describe '#fetch_tickets' do
|
71
71
|
it 'fetches tickets from servers one at a time' do
|
72
|
-
Net::HTTP.should_receive(:get).and_return(
|
72
|
+
Net::HTTP.should_receive(:get).and_return({'first' => 1, 'increment' => 1, 'count' => 5}.to_json)
|
73
73
|
client = TickrClient.new(
|
74
74
|
servers: [
|
75
75
|
{host: '127.0.0.1', port: 8080},
|
@@ -91,7 +91,7 @@ describe TickrClient do
|
|
91
91
|
|
92
92
|
describe '#fetch_tickets_async' do
|
93
93
|
it 'fetches tickets in a separate thread' do
|
94
|
-
FakeWeb.register_uri :get, 'http://127.0.0.1:8080/tickets/create/10', body:
|
94
|
+
FakeWeb.register_uri :get, 'http://127.0.0.1:8080/tickets/create/10', body: {'first' => 1, 'increment' => 1, 'count' => 2}.to_json
|
95
95
|
client = TickrClient.new(
|
96
96
|
servers: [
|
97
97
|
{host: '127.0.0.1', port: 8080}
|
@@ -99,7 +99,7 @@ describe TickrClient do
|
|
99
99
|
cache_size: 10
|
100
100
|
)
|
101
101
|
client.send(:tickets=, [1, 2])
|
102
|
-
FakeWeb.register_uri :get, 'http://127.0.0.1:8080/tickets/create/8', body:
|
102
|
+
FakeWeb.register_uri :get, 'http://127.0.0.1:8080/tickets/create/8', body: {'first' => 5, 'increment' => 1, 'count' => 8}.to_json
|
103
103
|
|
104
104
|
client.send(:fetch_tickets_async)
|
105
105
|
client.send(:tickets).should == [1, 2] # Thread will not have finished yet
|
@@ -130,7 +130,7 @@ describe TickrClient do
|
|
130
130
|
client.send(:tickets=, [1, 2])
|
131
131
|
client.send(:next_server_index=, 1)
|
132
132
|
|
133
|
-
FakeWeb.register_uri :get, 'http://127.0.0.1:8081/tickets/create/8', body:
|
133
|
+
FakeWeb.register_uri :get, 'http://127.0.0.1:8081/tickets/create/8', body: {'first' => 5, 'increment' => 1, 'count' => 8}.to_json
|
134
134
|
|
135
135
|
client.send(:fetch_tickets_from_server, 1).should be_true
|
136
136
|
client.send(:tickets).should == [1, 2, 5, 6, 7, 8, 9, 10, 11, 12]
|
@@ -152,7 +152,7 @@ describe TickrClient do
|
|
152
152
|
TickrClient.any_instance.stub :fetch_tickets
|
153
153
|
|
154
154
|
client = get_client
|
155
|
-
tickets = client.send(:create_tickets_from_ticket_group,
|
155
|
+
tickets = client.send(:create_tickets_from_ticket_group, {'first' => 100, 'increment' => 100, 'count' => 5})
|
156
156
|
tickets.should == [100, 200, 300, 400, 500]
|
157
157
|
end
|
158
158
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "tickr_client"
|
8
|
+
s.version = "1.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Robby Grossman"]
|
12
|
+
s.date = "2013-07-30"
|
13
|
+
s.description = "A Ruby Client for interacting with a Tickr server"
|
14
|
+
s.email = "robby@freerobby.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".rspec",
|
22
|
+
".rvmrc",
|
23
|
+
"Gemfile",
|
24
|
+
"Gemfile.lock",
|
25
|
+
"LICENSE.txt",
|
26
|
+
"README.md",
|
27
|
+
"Rakefile",
|
28
|
+
"VERSION",
|
29
|
+
"lib/tickr/interfaces/active_record.rb",
|
30
|
+
"lib/tickr_client.rb",
|
31
|
+
"spec/lib/tickr/interfaces/active_record_spec.rb",
|
32
|
+
"spec/spec_helper.rb",
|
33
|
+
"spec/tickr_client_spec.rb",
|
34
|
+
"tickr_client.gemspec"
|
35
|
+
]
|
36
|
+
s.homepage = "http://github.com/wistia/tickr-ruby-client"
|
37
|
+
s.licenses = ["MIT"]
|
38
|
+
s.require_paths = ["lib"]
|
39
|
+
s.rubygems_version = "1.8.25"
|
40
|
+
s.summary = "A Ruby Client for interacting with a Tickr server"
|
41
|
+
|
42
|
+
if s.respond_to? :specification_version then
|
43
|
+
s.specification_version = 3
|
44
|
+
|
45
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
46
|
+
s.add_runtime_dependency(%q<thread_safe>, ["~> 0.1"])
|
47
|
+
s.add_runtime_dependency(%q<json>, ["~> 1.8"])
|
48
|
+
s.add_development_dependency(%q<activerecord>, [">= 2.3.0"])
|
49
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.2"])
|
50
|
+
s.add_development_dependency(%q<fakeweb>, ["~> 1.3"])
|
51
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8"])
|
52
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.13"])
|
53
|
+
s.add_development_dependency(%q<sqlite3>, ["~> 1.3"])
|
54
|
+
else
|
55
|
+
s.add_dependency(%q<thread_safe>, ["~> 0.1"])
|
56
|
+
s.add_dependency(%q<json>, ["~> 1.8"])
|
57
|
+
s.add_dependency(%q<activerecord>, [">= 2.3.0"])
|
58
|
+
s.add_dependency(%q<bundler>, ["~> 1.2"])
|
59
|
+
s.add_dependency(%q<fakeweb>, ["~> 1.3"])
|
60
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8"])
|
61
|
+
s.add_dependency(%q<rspec>, ["~> 2.13"])
|
62
|
+
s.add_dependency(%q<sqlite3>, ["~> 1.3"])
|
63
|
+
end
|
64
|
+
else
|
65
|
+
s.add_dependency(%q<thread_safe>, ["~> 0.1"])
|
66
|
+
s.add_dependency(%q<json>, ["~> 1.8"])
|
67
|
+
s.add_dependency(%q<activerecord>, [">= 2.3.0"])
|
68
|
+
s.add_dependency(%q<bundler>, ["~> 1.2"])
|
69
|
+
s.add_dependency(%q<fakeweb>, ["~> 1.3"])
|
70
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8"])
|
71
|
+
s.add_dependency(%q<rspec>, ["~> 2.13"])
|
72
|
+
s.add_dependency(%q<sqlite3>, ["~> 1.3"])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tickr_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-07-
|
12
|
+
date: 2013-07-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: thread_safe
|
@@ -43,6 +43,22 @@ dependencies:
|
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '1.8'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: activerecord
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 2.3.0
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.3.0
|
46
62
|
- !ruby/object:Gem::Dependency
|
47
63
|
name: bundler
|
48
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,6 +123,22 @@ dependencies:
|
|
107
123
|
- - ~>
|
108
124
|
- !ruby/object:Gem::Version
|
109
125
|
version: '2.13'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: sqlite3
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ~>
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '1.3'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ~>
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '1.3'
|
110
142
|
description: A Ruby Client for interacting with a Tickr server
|
111
143
|
email: robby@freerobby.com
|
112
144
|
executables: []
|
@@ -124,9 +156,12 @@ files:
|
|
124
156
|
- README.md
|
125
157
|
- Rakefile
|
126
158
|
- VERSION
|
159
|
+
- lib/tickr/interfaces/active_record.rb
|
127
160
|
- lib/tickr_client.rb
|
161
|
+
- spec/lib/tickr/interfaces/active_record_spec.rb
|
128
162
|
- spec/spec_helper.rb
|
129
163
|
- spec/tickr_client_spec.rb
|
164
|
+
- tickr_client.gemspec
|
130
165
|
homepage: http://github.com/wistia/tickr-ruby-client
|
131
166
|
licenses:
|
132
167
|
- MIT
|
@@ -142,7 +177,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
142
177
|
version: '0'
|
143
178
|
segments:
|
144
179
|
- 0
|
145
|
-
hash:
|
180
|
+
hash: 453379598713018140
|
146
181
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
182
|
none: false
|
148
183
|
requirements:
|