copycopter_client 1.0.0.beta1 → 1.0.0.beta2
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/lib/copycopter_client/sync.rb +25 -4
- data/lib/copycopter_client/version.rb +1 -1
- data/lib/copycopter_client.rb +6 -0
- data/spec/copycopter_client/sync_spec.rb +63 -0
- data/spec/support/fake_resque_job.rb +11 -0
- metadata +10 -10
@@ -35,10 +35,13 @@ module CopycopterClient
|
|
35
35
|
if spawner?
|
36
36
|
register_spawn_hooks
|
37
37
|
else
|
38
|
+
register_job_hooks
|
38
39
|
logger.info("Starting poller")
|
39
40
|
@pending = true
|
40
41
|
at_exit { sync }
|
41
|
-
Thread.new { poll }
|
42
|
+
unless Thread.new { poll }
|
43
|
+
logger.error("Couldn't start poller thread")
|
44
|
+
end
|
42
45
|
end
|
43
46
|
end
|
44
47
|
|
@@ -78,6 +81,12 @@ module CopycopterClient
|
|
78
81
|
end
|
79
82
|
end
|
80
83
|
|
84
|
+
def flush
|
85
|
+
with_queued_changes do |queued|
|
86
|
+
client.upload(queued)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
81
90
|
private
|
82
91
|
|
83
92
|
attr_reader :client, :polling_delay, :logger
|
@@ -95,9 +104,7 @@ module CopycopterClient
|
|
95
104
|
begin
|
96
105
|
downloaded_blurbs = client.download
|
97
106
|
lock { @blurbs = downloaded_blurbs }
|
98
|
-
|
99
|
-
client.upload(queued)
|
100
|
-
end
|
107
|
+
flush
|
101
108
|
rescue ConnectionError => error
|
102
109
|
logger.error(error.message)
|
103
110
|
end
|
@@ -124,6 +131,20 @@ module CopycopterClient
|
|
124
131
|
$0.include?("ApplicationSpawner") || $0 =~ /unicorn.*master/
|
125
132
|
end
|
126
133
|
|
134
|
+
def register_job_hooks
|
135
|
+
if defined?(Resque)
|
136
|
+
logger.info("Registered Resque after_perform hook")
|
137
|
+
Resque::Job.class_eval do
|
138
|
+
alias_method :perform_without_copycopter, :perform
|
139
|
+
def perform
|
140
|
+
job_was_performed = perform_without_copycopter
|
141
|
+
CopycopterClient.flush
|
142
|
+
job_was_performed
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
127
148
|
def register_spawn_hooks
|
128
149
|
if defined?(PhusionPassenger)
|
129
150
|
logger.info("Registered Phusion Passenger fork hook")
|
data/lib/copycopter_client.rb
CHANGED
@@ -34,6 +34,12 @@ module CopycopterClient
|
|
34
34
|
sync.start
|
35
35
|
end
|
36
36
|
|
37
|
+
# Flush queued changed synchronously
|
38
|
+
# This is called from the Resque after perform "hook"
|
39
|
+
def self.flush
|
40
|
+
sync.flush
|
41
|
+
end
|
42
|
+
|
37
43
|
# Call this method to modify defaults in your initializers.
|
38
44
|
#
|
39
45
|
# @example
|
@@ -95,6 +95,17 @@ describe CopycopterClient::Sync do
|
|
95
95
|
client.uploaded.should == { 'test.key' => 'test value' }
|
96
96
|
end
|
97
97
|
|
98
|
+
it "uploads changes when flushed" do
|
99
|
+
sync = build_sync(:polling_delay => 86400)
|
100
|
+
sync.start
|
101
|
+
sleep 2
|
102
|
+
sync['test.key'] = 'test value'
|
103
|
+
sync.flush
|
104
|
+
sleep(2)
|
105
|
+
|
106
|
+
client.uploaded.should == { 'test.key' => 'test value' }
|
107
|
+
end
|
108
|
+
|
98
109
|
it "handles connection errors when polling" do
|
99
110
|
failure = "server is napping"
|
100
111
|
logger = FakeLogger.new
|
@@ -153,6 +164,39 @@ describe CopycopterClient::Sync do
|
|
153
164
|
"Got entries: #{logger.entries.inspect}"
|
154
165
|
end
|
155
166
|
|
167
|
+
it "flushes after running a resque job" do
|
168
|
+
define_constant('Resque', Module.new)
|
169
|
+
job = define_constant('Resque::Job', FakeResqueJob).new(:key => 'test.key', :value => 'all your base')
|
170
|
+
|
171
|
+
api_key = "12345"
|
172
|
+
FakeCopycopterApp.add_project api_key
|
173
|
+
logger = FakeLogger.new
|
174
|
+
|
175
|
+
config = { :logger => logger, :polling_delay => 86400, :api_key => api_key }
|
176
|
+
default_config = CopycopterClient::Configuration.new.to_hash.update(config)
|
177
|
+
real_client = CopycopterClient::Client.new(default_config)
|
178
|
+
sync = CopycopterClient::Sync.new(real_client, default_config)
|
179
|
+
CopycopterClient.sync = sync
|
180
|
+
job.sync = sync
|
181
|
+
|
182
|
+
sync.start
|
183
|
+
sleep(2)
|
184
|
+
|
185
|
+
logger.should have_entry(:info, "Registered Resque after_perform hook")
|
186
|
+
|
187
|
+
if fork
|
188
|
+
Process.wait
|
189
|
+
else
|
190
|
+
job.perform
|
191
|
+
exit!
|
192
|
+
end
|
193
|
+
sleep(2)
|
194
|
+
|
195
|
+
project = FakeCopycopterApp.project(api_key)
|
196
|
+
project.draft['test.key'].should == 'all your base'
|
197
|
+
|
198
|
+
end
|
199
|
+
|
156
200
|
it "starts after spawning when using unicorn" do
|
157
201
|
logger = FakeLogger.new
|
158
202
|
define_constant('Unicorn', Module.new)
|
@@ -232,6 +276,15 @@ describe CopycopterClient::Sync do
|
|
232
276
|
logger.should_not have_entry(:info, "Waiting for first sync")
|
233
277
|
end
|
234
278
|
|
279
|
+
it "logs an error if the background thread can't start" do
|
280
|
+
Thread.stubs(:new => nil)
|
281
|
+
logger = FakeLogger.new
|
282
|
+
|
283
|
+
build_sync(:logger => logger).start
|
284
|
+
|
285
|
+
logger.should have_entry(:error, "Couldn't start poller thread")
|
286
|
+
end
|
287
|
+
|
235
288
|
describe "given locked mutex" do
|
236
289
|
Spec::Matchers.define :finish_after_unlocking do |mutex|
|
237
290
|
match do |thread|
|
@@ -291,5 +344,15 @@ describe CopycopterClient::Sync do
|
|
291
344
|
|
292
345
|
sync.should have_received(:start)
|
293
346
|
end
|
347
|
+
|
348
|
+
it "flushes from the top level" do
|
349
|
+
sync = build_sync
|
350
|
+
CopycopterClient.sync = sync
|
351
|
+
sync.stubs(:flush)
|
352
|
+
|
353
|
+
CopycopterClient.flush
|
354
|
+
|
355
|
+
sync.should have_received(:flush)
|
356
|
+
end
|
294
357
|
end
|
295
358
|
|
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: copycopter_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 299253594
|
5
|
+
prerelease: true
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
9
|
- 0
|
10
|
-
-
|
11
|
-
|
12
|
-
version: 1.0.0.beta1
|
10
|
+
- beta2
|
11
|
+
version: 1.0.0.beta2
|
13
12
|
platform: ruby
|
14
13
|
authors:
|
15
14
|
- thoughtbot
|
@@ -21,9 +20,10 @@ date: 2010-06-04 00:00:00 -04:00
|
|
21
20
|
default_executable:
|
22
21
|
dependencies:
|
23
22
|
- !ruby/object:Gem::Dependency
|
24
|
-
|
23
|
+
type: :runtime
|
25
24
|
prerelease: false
|
26
|
-
|
25
|
+
name: i18n
|
26
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
27
27
|
none: false
|
28
28
|
requirements:
|
29
29
|
- - ">="
|
@@ -32,8 +32,7 @@ dependencies:
|
|
32
32
|
segments:
|
33
33
|
- 0
|
34
34
|
version: "0"
|
35
|
-
|
36
|
-
version_requirements: *id001
|
35
|
+
requirement: *id001
|
37
36
|
description:
|
38
37
|
email: support@thoughtbot.com
|
39
38
|
executables: []
|
@@ -73,6 +72,7 @@ files:
|
|
73
72
|
- spec/support/fake_html_safe_string.rb
|
74
73
|
- spec/support/fake_logger.rb
|
75
74
|
- spec/support/fake_passenger.rb
|
75
|
+
- spec/support/fake_resque_job.rb
|
76
76
|
- spec/support/fake_unicorn.rb
|
77
77
|
- features/rails.feature
|
78
78
|
- features/step_definitions/copycopter_server_steps.rb
|
@@ -113,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
113
|
requirements: []
|
114
114
|
|
115
115
|
rubyforge_project: copycopter_client
|
116
|
-
rubygems_version: 1.
|
116
|
+
rubygems_version: 1.3.7
|
117
117
|
signing_key:
|
118
118
|
specification_version: 3
|
119
119
|
summary: Client for the Copycopter content management service
|