tickr_client 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -4,8 +4,10 @@ gem 'thread_safe', '~> 0.1'
4
4
  gem 'json', '~> 1.8'
5
5
 
6
6
  group :development do
7
+ gem 'activerecord', '>= 2.3.0'
7
8
  gem 'bundler', '~> 1.2'
8
9
  gem 'fakeweb', '~> 1.3'
9
10
  gem 'jeweler', '~> 1.8'
10
11
  gem 'rspec', '~> 2.13'
12
+ gem 'sqlite3', '~> 1.3'
11
13
  end
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 directly. TickrClients are threadsafe and the `#get_ticket` method may be called safely on a single instance from all of your request handlers and workers.
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 makes no guarantee about sequentiality.
12
+ Note that the threadsafe guarantee for a ticket is only its uniqueness; tickr
13
+ makes no guarantee about sequentiality.
10
14
 
11
- $my_tickr = TickrClient.new(
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 = $my_tickr.get_ticket
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
+ 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
- FakeWeb.allow_net_connect = false
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
@@ -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([1, 2, 3, 4, 5].to_json)
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: [1, 1, 2].to_json
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: [5, 1, 8].to_json
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: [5, 1, 8].to_json
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, [100, 100, 5])
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.1
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-18 00:00:00.000000000 Z
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: -4284658083442582303
180
+ hash: 453379598713018140
146
181
  required_rubygems_version: !ruby/object:Gem::Requirement
147
182
  none: false
148
183
  requirements: