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 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: