rhosync 2.1.0.beta.2 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +2 -0
- data/Rakefile +1 -1
- data/lib/rhosync/client_sync.rb +11 -38
- data/lib/rhosync/source.rb +0 -5
- data/lib/rhosync/source_adapter.rb +1 -6
- data/lib/rhosync/source_sync.rb +4 -34
- data/lib/rhosync/tasks.rb +32 -2
- data/spec/api/get_source_params_spec.rb +1 -2
- data/spec/api/rhosync_api_spec.rb +1 -2
- data/spec/client_sync_spec.rb +0 -13
- data/spec/source_sync_spec.rb +3 -13
- data/tasks/redis.rake +22 -3
- metadata +8 -12
data/CHANGELOG
CHANGED
@@ -14,6 +14,8 @@
|
|
14
14
|
* #7034095 - don't ping device if device_pin is empty or nil
|
15
15
|
* #7089047 - fixed application.rb template store_blob method
|
16
16
|
* #7055889 - fixed schema tables should have 'object' primary key
|
17
|
+
* #7217581 - use REDIS_HOME env var if it exists for rake redis:* tasks
|
18
|
+
* #6645553 - detect and run thin if available, fallback to mongrel and die on webrick
|
17
19
|
|
18
20
|
## 2.0.9
|
19
21
|
* #5154725 - stats framework
|
data/Rakefile
CHANGED
@@ -60,7 +60,7 @@ begin
|
|
60
60
|
gemspec.homepage = %q{http://rhomobile.com/products/rhosync}
|
61
61
|
gemspec.authors = ["Rhomobile"]
|
62
62
|
gemspec.email = %q{dev@rhomobile.com}
|
63
|
-
gemspec.version =
|
63
|
+
gemspec.version = Rhosync::VERSION
|
64
64
|
gemspec.files = FileList["[A-Z]*", "{bench,bin,generators,lib,spec,tasks}/**/*"]
|
65
65
|
|
66
66
|
# TODO: Due to https://www.pivotaltracker.com/story/show/3417862, we can't use JSON 1.4.3
|
data/lib/rhosync/client_sync.rb
CHANGED
@@ -12,30 +12,22 @@ module Rhosync
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def receive_cud(cud_params={},query_params=nil)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
processed
|
20
|
-
['create','update','delete'].each do |op|
|
21
|
-
key,value = op,cud_params[op]
|
22
|
-
processed += _receive_cud(key,value) if value
|
23
|
-
end
|
24
|
-
@source_sync.process_cud(@client.id) if processed > 0
|
15
|
+
_process_blobs(cud_params)
|
16
|
+
processed = 0
|
17
|
+
['create','update','delete'].each do |op|
|
18
|
+
key,value = op,cud_params[op]
|
19
|
+
processed += _receive_cud(key,value) if value
|
25
20
|
end
|
21
|
+
@source_sync.process_cud(@client.id) if processed > 0
|
26
22
|
end
|
27
23
|
|
28
24
|
def send_cud(token=nil,query_params=nil)
|
29
25
|
res = []
|
30
|
-
if not _ack_token(token)
|
26
|
+
if not _ack_token(token)
|
31
27
|
res = resend_page(token)
|
32
28
|
else
|
33
|
-
|
34
|
-
|
35
|
-
res = send_pass_through_data(query_result)
|
36
|
-
else
|
37
|
-
res = send_new_page
|
38
|
-
end
|
29
|
+
@source_sync.process_query(query_params)
|
30
|
+
res = send_new_page
|
39
31
|
end
|
40
32
|
_format_result(res[0],res[1],res[2],res[3])
|
41
33
|
end
|
@@ -85,25 +77,6 @@ module Rhosync
|
|
85
77
|
[token,progress_count,total_count,res]
|
86
78
|
end
|
87
79
|
|
88
|
-
def send_pass_through_data(data)
|
89
|
-
data ||= {}
|
90
|
-
data.each_key do |object_id|
|
91
|
-
data[object_id].each { |attrib,value| data[object_id][attrib] = '' if value.nil? }
|
92
|
-
end
|
93
|
-
token = ''
|
94
|
-
compute_errors_page
|
95
|
-
res = build_page do |r|
|
96
|
-
r['insert'] = data
|
97
|
-
r['metadata'] = compute_metadata
|
98
|
-
end
|
99
|
-
if res['insert']
|
100
|
-
token = compute_token(@client.docname(:page_token))
|
101
|
-
else
|
102
|
-
_delete_errors_page
|
103
|
-
end
|
104
|
-
[token,0,data.size,res]
|
105
|
-
end
|
106
|
-
|
107
80
|
# Resend token for a client, also sends exceptions
|
108
81
|
def resend_page(token=nil)
|
109
82
|
token,progress_count,total_count,res = '',0,0,{}
|
@@ -298,8 +271,8 @@ module Rhosync
|
|
298
271
|
def _do_search(params={})
|
299
272
|
# call source adapter search unless client is sending token for ack
|
300
273
|
search_params = params[:search] if params
|
301
|
-
|
302
|
-
res,diffsize =
|
274
|
+
@source_sync.search(@client.id,search_params) if params.nil? or !params[:token]
|
275
|
+
res,diffsize = compute_search
|
303
276
|
formatted_res = _format_search_result(res,diffsize)
|
304
277
|
@client.flash_data('search*') if diffsize == 0
|
305
278
|
formatted_res
|
data/lib/rhosync/source.rb
CHANGED
@@ -15,7 +15,6 @@ module Rhosync
|
|
15
15
|
field :queue,:string
|
16
16
|
field :query_queue,:string
|
17
17
|
field :cud_queue,:string
|
18
|
-
field :pass_through,:string
|
19
18
|
attr_accessor :app_id, :user_id
|
20
19
|
validates_presence_of :name #, :source_id
|
21
20
|
|
@@ -146,10 +145,6 @@ module Rhosync
|
|
146
145
|
yield client_id,params if need_refresh
|
147
146
|
end
|
148
147
|
|
149
|
-
def is_pass_through?
|
150
|
-
self.pass_through and self.pass_through == 'true'
|
151
|
-
end
|
152
|
-
|
153
148
|
private
|
154
149
|
def self.validate_attributes(params)
|
155
150
|
raise ArgumentError.new('Missing required attribute user_id') unless params[:user_id]
|
@@ -62,12 +62,7 @@ module Rhosync
|
|
62
62
|
@tmp_docname = @source.docname(:md) + get_random_uuid
|
63
63
|
@stash_size = 0
|
64
64
|
params ? self.query(params) : self.query
|
65
|
-
|
66
|
-
@result
|
67
|
-
else
|
68
|
-
self.sync
|
69
|
-
true
|
70
|
-
end
|
65
|
+
self.sync
|
71
66
|
end
|
72
67
|
|
73
68
|
def stash_result
|
data/lib/rhosync/source_sync.rb
CHANGED
@@ -22,33 +22,6 @@ module Rhosync
|
|
22
22
|
_measure_and_process_cud('delete',client_id)
|
23
23
|
end
|
24
24
|
|
25
|
-
# Pass through CUD to adapter, no data stored
|
26
|
-
def pass_through_cud(cud_params,query_params)
|
27
|
-
res,processed_objects = {},[]
|
28
|
-
begin
|
29
|
-
['create','update','delete'].each do |op|
|
30
|
-
key,objects = op,cud_params[op]
|
31
|
-
objects.each do |key,value|
|
32
|
-
case op
|
33
|
-
when 'create'
|
34
|
-
@adapter.send(op.to_sym,value)
|
35
|
-
when 'update'
|
36
|
-
value['id'] = key
|
37
|
-
@adapter.send(op.to_sym,value)
|
38
|
-
when 'delete'
|
39
|
-
@adapter.send(op.to_sym,key)
|
40
|
-
end
|
41
|
-
process_objects << key
|
42
|
-
end if objects
|
43
|
-
end
|
44
|
-
rescue Exception => e
|
45
|
-
log "Error in #{op} pass through method: #{e.message}"
|
46
|
-
res['error'] = { 'operation' => op, 'message' => e.message }
|
47
|
-
end
|
48
|
-
res['processed'] = process_objects
|
49
|
-
res.to_json
|
50
|
-
end
|
51
|
-
|
52
25
|
# Read Operation; params are query arguments
|
53
26
|
def read(client_id=nil,params=nil)
|
54
27
|
_read('query',client_id,params)
|
@@ -86,15 +59,13 @@ module Rhosync
|
|
86
59
|
end
|
87
60
|
|
88
61
|
def do_query(params=nil)
|
89
|
-
result = nil
|
90
62
|
@source.if_need_refresh do
|
91
63
|
Stats::Record.update("source:query:#{@source.name}") do
|
92
64
|
return if _auth_op('login') == false
|
93
|
-
|
65
|
+
self.read(nil,params)
|
94
66
|
_auth_op('logoff')
|
95
67
|
end
|
96
68
|
end
|
97
|
-
result
|
98
69
|
end
|
99
70
|
|
100
71
|
# Enqueue a job for the source based on job type
|
@@ -252,20 +223,19 @@ module Rhosync
|
|
252
223
|
# Read Operation; params are query arguments
|
253
224
|
def _read(operation,client_id,params=nil)
|
254
225
|
errordoc = nil
|
255
|
-
result = nil
|
256
226
|
begin
|
257
227
|
if operation == 'search'
|
258
228
|
client = Client.load(client_id,{:source_name => @source.name})
|
259
229
|
errordoc = client.docname(:search_errors)
|
260
230
|
compute_token(client.docname(:search_token))
|
261
|
-
|
231
|
+
@adapter.search(params)
|
262
232
|
@adapter.save(client.docname(:search))
|
263
233
|
else
|
264
234
|
errordoc = @source.docname(:errors)
|
265
235
|
[:metadata,:schema].each do |method|
|
266
236
|
_get_data(method)
|
267
237
|
end
|
268
|
-
|
238
|
+
@adapter.do_query(params)
|
269
239
|
end
|
270
240
|
# operation,sync succeeded, remove errors
|
271
241
|
Store.lock(errordoc) do
|
@@ -278,7 +248,7 @@ module Rhosync
|
|
278
248
|
Store.put_data(errordoc,{"#{operation}-error"=>{'message'=>e.message}},true)
|
279
249
|
end
|
280
250
|
end
|
281
|
-
|
251
|
+
true
|
282
252
|
end
|
283
253
|
end
|
284
254
|
end
|
data/lib/rhosync/tasks.rb
CHANGED
@@ -50,6 +50,35 @@ module Rhosync
|
|
50
50
|
def windows?
|
51
51
|
RUBY_PLATFORM =~ /(win|w)32$/
|
52
52
|
end
|
53
|
+
|
54
|
+
def thin?
|
55
|
+
begin
|
56
|
+
require 'thin'
|
57
|
+
'rackup -s thin'
|
58
|
+
rescue LoadError
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def mongrel?
|
64
|
+
begin
|
65
|
+
require 'mongrel'
|
66
|
+
'rackup -s mongrel'
|
67
|
+
rescue LoadError
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def report_missing_server
|
73
|
+
msg =<<-EOF
|
74
|
+
Could not find 'thin' or 'mongrel' on your system. Please install one:
|
75
|
+
gem install thin
|
76
|
+
or
|
77
|
+
gem install mongrel
|
78
|
+
EOF
|
79
|
+
puts msg
|
80
|
+
exit 1
|
81
|
+
end
|
53
82
|
end
|
54
83
|
end
|
55
84
|
|
@@ -206,13 +235,14 @@ namespace :rhosync do
|
|
206
235
|
|
207
236
|
desc "Start rhosync server"
|
208
237
|
task :start => :dtach_installed do
|
238
|
+
cmd = thin? || mongrel? || report_missing_server
|
209
239
|
if windows?
|
210
240
|
puts 'Starting server in new window...'
|
211
|
-
system(
|
241
|
+
system("start cmd.exe /c #{cmd} config.ru")
|
212
242
|
else
|
213
243
|
puts 'Detach with Ctrl+\ Re-attach with rake rhosync:attach'
|
214
244
|
sleep 2
|
215
|
-
sh "dtach -A #{rhosync_socket}
|
245
|
+
sh "dtach -A #{rhosync_socket} #{cmd} config.ru -P #{rhosync_pid}"
|
216
246
|
end
|
217
247
|
end
|
218
248
|
|
@@ -21,8 +21,7 @@ describe "RhosyncApiGetSourceParams" do
|
|
21
21
|
{"name"=>"has_many", "type"=>"string", "value"=>"FixedSchemaAdapter,brand"},
|
22
22
|
{"name"=>"queue", "value"=>nil, "type"=>"string"},
|
23
23
|
{"name"=>"query_queue", "value"=>nil, "type"=>"string"},
|
24
|
-
{"name"=>"cud_queue", "value"=>nil, "type"=>"string"}
|
25
|
-
{"name"=>"pass_through", "value"=>nil, "type"=>"string"}]
|
24
|
+
{"name"=>"cud_queue", "value"=>nil, "type"=>"string"}]
|
26
25
|
end
|
27
26
|
|
28
27
|
end
|
@@ -168,8 +168,7 @@ describe "RhosyncApi" do
|
|
168
168
|
{"name"=>"has_many", "type"=>"string", "value"=>"FixedSchemaAdapter,brand"},
|
169
169
|
{"name"=>"queue", "value"=>nil, "type"=>"string"},
|
170
170
|
{"name"=>"query_queue", "value"=>nil, "type"=>"string"},
|
171
|
-
{"name"=>"cud_queue", "value"=>nil, "type"=>"string"}
|
172
|
-
{"name"=>"pass_through", "value"=>nil, "type"=>"string"}]
|
171
|
+
{"name"=>"cud_queue", "value"=>nil, "type"=>"string"}]
|
173
172
|
end
|
174
173
|
|
175
174
|
it "should list source attributes using rest call" do
|
data/spec/client_sync_spec.rb
CHANGED
@@ -35,19 +35,6 @@ describe "ClientSync" do
|
|
35
35
|
@cs.client.docname(:cd) => data)
|
36
36
|
end
|
37
37
|
|
38
|
-
it "should handle send cud if pass_through is set" do
|
39
|
-
data = {'1'=>@product1,'2'=>@product2}
|
40
|
-
expected = {'insert'=>data}
|
41
|
-
set_test_data('test_db_storage',data)
|
42
|
-
@s.pass_through = 'true'
|
43
|
-
@cs.send_cud.should == [{'version'=>ClientSync::VERSION},
|
44
|
-
{'token'=>@c.get_value(:page_token)},
|
45
|
-
{'count'=>data.size},{'progress_count'=>data.size},
|
46
|
-
{'total_count'=>data.size},expected]
|
47
|
-
verify_result(@cs.client.docname(:page) => {},
|
48
|
-
@cs.client.docname(:cd) => {})
|
49
|
-
end
|
50
|
-
|
51
38
|
it "should return read errors in send cud" do
|
52
39
|
msg = "Error during query"
|
53
40
|
data = {'1'=>@product1,'2'=>@product2}
|
data/spec/source_sync_spec.rb
CHANGED
@@ -105,16 +105,6 @@ describe "SourceSync" do
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
|
-
it "should process source adapter with pass_through set" do
|
109
|
-
expected = {'1'=>@product1,'2'=>@product2}
|
110
|
-
set_state('test_db_storage' => expected)
|
111
|
-
@s.pass_through = 'true'
|
112
|
-
@ss.process_query.should == expected
|
113
|
-
verify_result(@s.docname(:md) => {},
|
114
|
-
@s.docname(:md_size) => nil)
|
115
|
-
@s.pass_through = nil
|
116
|
-
end
|
117
|
-
|
118
108
|
describe "create" do
|
119
109
|
it "should do create where adapter.create returns nil" do
|
120
110
|
set_state(@c.docname(:create) => {'2'=>@product2})
|
@@ -240,7 +230,7 @@ describe "SourceSync" do
|
|
240
230
|
verify_result(@s.docname(:md) => expected,
|
241
231
|
@s.docname(:errors) => {})
|
242
232
|
else
|
243
|
-
@ss.search(@c.id).should ==
|
233
|
+
@ss.search(@c.id).should == true
|
244
234
|
verify_result(@c.docname(:search) => expected,
|
245
235
|
@c.docname(:search_errors) => {})
|
246
236
|
end
|
@@ -251,11 +241,11 @@ describe "SourceSync" do
|
|
251
241
|
@ss.should_receive(:log).with("SourceAdapter raised #{operation} exception: #{msg}")
|
252
242
|
set_test_data('test_db_storage',{},msg,"#{operation} error")
|
253
243
|
if operation == 'query'
|
254
|
-
@ss.read.should
|
244
|
+
@ss.read.should == true
|
255
245
|
verify_result(@s.docname(:md) => {},
|
256
246
|
@s.docname(:errors) => {'query-error'=>{'message'=>msg}})
|
257
247
|
else
|
258
|
-
@ss.search(@c.id).should
|
248
|
+
@ss.search(@c.id).should == true
|
259
249
|
verify_result(@c.docname(:search) => {},
|
260
250
|
@c.docname(:search_errors) => {'search-error'=>{'message'=>msg}})
|
261
251
|
end
|
data/tasks/redis.rake
CHANGED
@@ -11,6 +11,19 @@ if windows?
|
|
11
11
|
$redis_zip = "C:/#{$redis_ver}.zip"
|
12
12
|
$redis_dest = "C:/"
|
13
13
|
end
|
14
|
+
|
15
|
+
def redis_home
|
16
|
+
ENV['REDIS_HOME'] || File.join($redis_dest,$redis_ver)
|
17
|
+
end
|
18
|
+
|
19
|
+
def mk_bin_dir(bin_dir)
|
20
|
+
begin
|
21
|
+
mkdir_p bin_dir unless File.exists?(bin_dir)
|
22
|
+
rescue
|
23
|
+
puts "Can't create #{bin_dir}, maybe you need to run command as root?"
|
24
|
+
exit 1
|
25
|
+
end
|
26
|
+
end
|
14
27
|
|
15
28
|
class RedisRunner
|
16
29
|
|
@@ -43,7 +56,7 @@ class RedisRunner
|
|
43
56
|
def self.start
|
44
57
|
if windows?
|
45
58
|
puts "Starting redis in a new window..."
|
46
|
-
sh "start #{File.join(
|
59
|
+
sh "start #{File.join(redis_home,'redis-server')}" rescue
|
47
60
|
"redis-server not installed on your path, please run 'rake redis:install' first."
|
48
61
|
else
|
49
62
|
puts 'Detach with Ctrl+\ Re-attach with rake redis:attach'
|
@@ -95,6 +108,9 @@ namespace :redis do
|
|
95
108
|
task :install => [:about, :download, :make] do
|
96
109
|
unless windows?
|
97
110
|
ENV['PREFIX'] and bin_dir = "#{ENV['PREFIX']}/bin" or bin_dir = "#{RedisRunner.prefix}bin"
|
111
|
+
|
112
|
+
mk_bin_dir(bin_dir)
|
113
|
+
|
98
114
|
%w(redis-benchmark redis-cli redis-server).each do |bin|
|
99
115
|
sh "cp /tmp/redis/#{bin} #{bin_dir}"
|
100
116
|
end
|
@@ -123,7 +139,7 @@ namespace :redis do
|
|
123
139
|
require 'net/http'
|
124
140
|
require 'zip/zip'
|
125
141
|
|
126
|
-
puts "Installing redis to #{
|
142
|
+
puts "Installing redis to #{redis_home}."
|
127
143
|
|
128
144
|
Net::HTTP.start("servicestack.googlecode.com") do |http|
|
129
145
|
resp = http.get("/files/#{$redis_ver}.zip")
|
@@ -144,7 +160,7 @@ namespace :redis do
|
|
144
160
|
else
|
145
161
|
sh 'rm -rf /tmp/redis/' if File.exists?("#{RedisRunner.redisdir}")
|
146
162
|
sh 'git clone git://github.com/antirez/redis.git /tmp/redis -n'
|
147
|
-
sh "cd #{RedisRunner.redisdir} && git reset --hard && git checkout v2.0.
|
163
|
+
sh "cd #{RedisRunner.redisdir} && git reset --hard && git checkout v2.0.4-stable"
|
148
164
|
end
|
149
165
|
end
|
150
166
|
|
@@ -173,6 +189,9 @@ namespace :dtach do
|
|
173
189
|
end
|
174
190
|
|
175
191
|
ENV['PREFIX'] and bin_dir = "#{ENV['PREFIX']}/bin" or bin_dir = "#{RedisRunner.prefix}bin"
|
192
|
+
|
193
|
+
mk_bin_dir(bin_dir)
|
194
|
+
|
176
195
|
Dir.chdir('/tmp/dtach-0.8/')
|
177
196
|
sh 'cd /tmp/dtach-0.8/ && ./configure && make'
|
178
197
|
sh "cp /tmp/dtach-0.8/dtach #{bin_dir}"
|
metadata
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rhosync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 11
|
5
|
+
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 1
|
9
9
|
- 0
|
10
|
-
|
11
|
-
- 2
|
12
|
-
version: 2.1.0.beta.2
|
10
|
+
version: 2.1.0
|
13
11
|
platform: ruby
|
14
12
|
authors:
|
15
13
|
- Rhomobile
|
@@ -17,7 +15,7 @@ autorequire:
|
|
17
15
|
bindir: bin
|
18
16
|
cert_chain: []
|
19
17
|
|
20
|
-
date: 2010-12-
|
18
|
+
date: 2010-12-14 00:00:00 -08:00
|
21
19
|
default_executable: rhosync
|
22
20
|
dependencies:
|
23
21
|
- !ruby/object:Gem::Dependency
|
@@ -567,14 +565,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
567
565
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
568
566
|
none: false
|
569
567
|
requirements:
|
570
|
-
- - "
|
568
|
+
- - ">="
|
571
569
|
- !ruby/object:Gem::Version
|
572
|
-
hash:
|
570
|
+
hash: 3
|
573
571
|
segments:
|
574
|
-
-
|
575
|
-
|
576
|
-
- 1
|
577
|
-
version: 1.3.1
|
572
|
+
- 0
|
573
|
+
version: "0"
|
578
574
|
requirements: []
|
579
575
|
|
580
576
|
rubyforge_project:
|