rhoconnect 4.0.0.beta.12 → 4.0.0.beta.24

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/CHANGELOG.md +34 -0
  2. data/Gemfile +5 -8
  3. data/Gemfile.lock +34 -32
  4. data/Rakefile +2 -12
  5. data/bench/run_bench.sh +1 -1
  6. data/bench/spec/bench_spec_helper.rb +3 -5
  7. data/bin/rhoconnect +20 -13
  8. data/commands/dtach/dtach_install.rb +3 -3
  9. data/commands/generators/update.rb +1 -0
  10. data/commands/parser.rb +180 -0
  11. data/commands/rhoconnect/config.rb +8 -4
  12. data/commands/rhoconnect/get_token.rb +3 -1
  13. data/commands/rhoconnect/routes.rb +34 -0
  14. data/commands/rhoconnect/secret.rb +1 -1
  15. data/commands/rhoconnect/set_admin_password.rb +2 -1
  16. data/commands/rhoconnect/startbg.rb +4 -4
  17. data/commands/rhoconnect/stop.rb +2 -2
  18. data/commands/rhoconnect_console/console.rb +6 -6
  19. data/commands/rhoconnect_spec/spec.rb +2 -1
  20. data/commands/rhoconnect_war/war.rb +1 -0
  21. data/commands/utilities/redis_runner.rb +2 -2
  22. data/doc/data-partitioning.txt +20 -7
  23. data/doc/extending-rhoconnect-server.txt +36 -7
  24. data/doc/push-client-setup-rps.txt +3 -3
  25. data/doc/source-adapters-js.txt +41 -4
  26. data/doc/source-adapters.txt +3 -0
  27. data/generators/templates/application/rcgemfile +1 -5
  28. data/generators/templates/application/spec/spec_helper.rb +0 -9
  29. data/generators/templates/source/models/js/model.js +8 -0
  30. data/generators/templates/source/models/ruby/model.rb +5 -11
  31. data/install.sh +2 -2
  32. data/installer/unix-like/rho_connect_install_constants.rb +3 -3
  33. data/installer/utils/delete_from_s3.rb +3 -6
  34. data/installer/utils/download_from_s3.rb +5 -9
  35. data/installer/utils/verify_checksum.rb +16 -11
  36. data/js-adapters/ballroom.js +9 -0
  37. data/js-adapters/exceptions.js +60 -0
  38. data/js-adapters/node.rb +14 -5
  39. data/js-adapters/node_channel.rb +68 -48
  40. data/js-adapters/rhoconnect_helpers.js +8 -2
  41. data/js-adapters/router.js +16 -14
  42. data/lib/rhoconnect.rb +5 -5
  43. data/lib/rhoconnect/client.rb +2 -2
  44. data/lib/rhoconnect/condition/add_parameter.rb +21 -0
  45. data/lib/rhoconnect/controller/clients_controller.rb +1 -1
  46. data/lib/rhoconnect/controller/js_base.rb +1 -2
  47. data/lib/rhoconnect/controller/system_controller.rb +33 -10
  48. data/lib/rhoconnect/db_adapter.rb +1 -1
  49. data/lib/rhoconnect/document.rb +11 -3
  50. data/lib/rhoconnect/handler/changes.rb +20 -19
  51. data/lib/rhoconnect/handler/changes/engine.rb +48 -25
  52. data/lib/rhoconnect/handler/changes/hooks.rb +36 -0
  53. data/lib/rhoconnect/handler/changes/runner.rb +12 -2
  54. data/lib/rhoconnect/handler/helpers.rb +4 -4
  55. data/lib/rhoconnect/jobs/source_job.rb +1 -1
  56. data/lib/rhoconnect/model/base.rb +32 -8
  57. data/lib/rhoconnect/model/helpers.rb +15 -0
  58. data/lib/rhoconnect/model/helpers/find_duplicates_on_update.rb +85 -0
  59. data/lib/rhoconnect/model/js_base.rb +23 -28
  60. data/lib/rhoconnect/server.rb +23 -18
  61. data/lib/rhoconnect/source.rb +10 -17
  62. data/lib/rhoconnect/store.rb +36 -57
  63. data/lib/rhoconnect/test_methods.rb +5 -4
  64. data/lib/rhoconnect/utilities.rb +7 -5
  65. data/lib/rhoconnect/version.rb +2 -2
  66. data/lib/rhoconnect/web-console/server.rb +17 -16
  67. data/rhoconnect.gemspec +23 -24
  68. data/spec/apps/rhotestapp/controllers/js/js_sample_controller.js +4 -0
  69. data/spec/apps/rhotestapp/models/js/js_sample.js +36 -0
  70. data/spec/apps/rhotestapp/models/ruby/sample_adapter.rb +34 -19
  71. data/spec/async_spec.rb +1 -1
  72. data/spec/cli/cli_spec.rb +69 -31
  73. data/spec/client_sync_spec.rb +30 -13
  74. data/spec/controllers/js_base_spec.rb +10 -4
  75. data/spec/jobs/source_job_spec.rb +1 -1
  76. data/spec/models/{js_model_spec.rb → js_base_spec.rb} +63 -13
  77. data/spec/server/server_spec.rb +20 -0
  78. data/spec/server/stats_spec.rb +7 -17
  79. data/spec/source_adapter_spec.rb +6 -0
  80. data/spec/source_sync_spec.rb +219 -54
  81. data/spec/spec_helper.rb +8 -13
  82. data/spec/store_spec.rb +6 -4
  83. data/spec/test_methods_spec.rb +4 -4
  84. metadata +14 -27
  85. data/commands/execute.rb +0 -48
  86. data/commands/utilities/utilities.rb +0 -6
  87. data/generators/templates/application/controllers/application_controller.rb +0 -17
  88. data/lib/rhoconnect/js_adapter.rb +0 -79
@@ -0,0 +1,36 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module Changes
4
+ module Hooks
5
+ def self.handler_installed(controller, rc_handler, verb, route_url, options)
6
+ queue_key = "#{verb}:#{route_url}"
7
+ # QUEUE key is unique per route
8
+ # standard routes - should go to the standard :create, :update, :delete queues
9
+ case queue_key
10
+ when "post:/", "put:/:id", "delete:/id"
11
+ queue_key = nil
12
+ end
13
+
14
+ queue_names = []
15
+ case rc_handler.to_sym
16
+ when :cud
17
+ queue_names << (queue_key ? "create:#{queue_key}" : "create")
18
+ queue_names << (queue_key ? "update:#{queue_key}" : "update")
19
+ queue_names << (queue_key ? "delete:#{queue_key}" : "delete")
20
+ when :create
21
+ queue_names << (queue_key ? "create:#{queue_key}" : "create")
22
+ when :update
23
+ queue_names << (queue_key ? "update:#{queue_key}" : "update")
24
+ when :delete
25
+ queue_names << (queue_key ? "delete:#{queue_key}" : "delete")
26
+ else
27
+ return true
28
+ end
29
+
30
+ Source.define_valid_queues(queue_names)
31
+ options[:add_parameter] = {:queue_key => queue_key} if queue_key
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -28,9 +28,19 @@ module Rhoconnect
28
28
  end
29
29
 
30
30
  private
31
- def _receive_cud(operation,params)
31
+ def _receive_cud(operation,cud_params)
32
32
  return 0 if not operations.include?(operation)
33
- @source.push_queue(operation,@client.id,params,true)
33
+ # build an Array if Hash (new operations are sequential)
34
+ obj_queue = cud_params
35
+ if cud_params.is_a?Hash
36
+ obj_queue = []
37
+ cud_params.each_pair do |key,obj|
38
+ obj_queue << [key, obj]
39
+ end
40
+ end
41
+ queue_key = params[:queue_key]
42
+ queue_name = (queue_key ? "#{operation}:#{queue_key}" : "#{operation}")
43
+ @source.push_queue(queue_name,@client.id,[[@source.name, obj_queue]],true)
34
44
  return 1
35
45
  end
36
46
 
@@ -1,4 +1,4 @@
1
- require 'rhoconnect/handler/helpers/auth_method.rb'
2
- require 'rhoconnect/handler/helpers/binding.rb'
3
- require 'rhoconnect/handler/helpers/source_job.rb'
4
- require 'rhoconnect/handler/helpers/bulk_data.rb'
1
+ require 'rhoconnect/handler/helpers/auth_method'
2
+ require 'rhoconnect/handler/helpers/binding'
3
+ require 'rhoconnect/handler/helpers/source_job'
4
+ require 'rhoconnect/handler/helpers/bulk_data'
@@ -18,7 +18,7 @@ module Rhoconnect
18
18
  handler_cud = lambda { @model.send params[:operation].to_sym, params["#{params[:operation]}_object".to_sym] }
19
19
  @model = Rhoconnect::Model::Base.create(source)
20
20
  source_cud = Rhoconnect::Handler::Changes::Engine.new(['create', 'update', 'delete'], @model, handler_cud, params)
21
- source_cud.do_cud
21
+ source_cud.run_cud
22
22
  end
23
23
  end
24
24
  end
@@ -1,3 +1,6 @@
1
+ require 'rhoconnect/model/helpers'
2
+ require 'rhoconnect/handler/helpers/binding'
3
+
1
4
  module Rhoconnect
2
5
  module Model
3
6
  class Exception < RuntimeError; end
@@ -12,6 +15,19 @@ module Rhoconnect
12
15
  class Base
13
16
  attr_accessor :session, :source
14
17
 
18
+ extend Rhoconnect::Model::Helpers
19
+ include Rhoconnect::Handler::Helpers::Binding
20
+
21
+ class << self
22
+ def enable(procname, options = {}, &block)
23
+ # installer suppose to do what's needed
24
+ if block_given?
25
+ options[:handler] = block
26
+ end
27
+ options = send "install_#{procname}", options
28
+ end
29
+ end
30
+
15
31
  def initialize(source)
16
32
  @source = source
17
33
  end
@@ -88,13 +104,13 @@ module Rhoconnect
88
104
  def search(params=nil); end
89
105
 
90
106
  def sync
91
- if @result and @result.empty?
107
+ if @result and @result.is_a?(Hash) and @result.empty?
92
108
  @source.lock(:md) do |s|
93
109
  s.flush_data(:md)
94
110
  s.put_value(:md_size,0)
95
111
  end
96
112
  else
97
- if @result
113
+ if @result and @result.is_a?(Hash)
98
114
  @source.put_tmp_data(@tmp_docname,@result)
99
115
  @stash_size += @result.size
100
116
  end
@@ -139,8 +155,21 @@ module Rhoconnect
139
155
  Rhoconnect.expire_bulk_data(current_user.login,partition)
140
156
  end
141
157
 
158
+ def run_validators(operation, operations_data, client_ids)
159
+ # run custom code
160
+ invalid_meta = validate(operation, operations_data, client_ids)
161
+ invalid_meta ||= {}
162
+ # run pre-installed validators
163
+ self.class.validators.each do |validator, options|
164
+ if options.has_key? operation.to_sym
165
+ invalid_meta = send validator.to_sym, options, invalid_meta, operation, operations_data, client_ids
166
+ end
167
+ end
168
+ invalid_meta
169
+ end
170
+
142
171
  # do pre-processing before CUD operation
143
- def validate(operation,operations_hashes,client_ids)
172
+ def validate(operation,operations_data,client_ids)
144
173
  {}
145
174
  end
146
175
 
@@ -154,11 +183,6 @@ module Rhoconnect
154
183
 
155
184
  def logoff; end
156
185
 
157
- # re-define in subc;ass to provide your own filename
158
- def store_blob(obj,field_name,blob)
159
- blob[:tempfile].path if blob[:tempfile]
160
- end
161
-
162
186
  # plugin callbacks implementation
163
187
  def push_objects(params)
164
188
  timeout = params[:timeout] || 10
@@ -0,0 +1,15 @@
1
+ require 'rhoconnect/model/helpers/find_duplicates_on_update'
2
+
3
+ module Rhoconnect
4
+ module Model
5
+ module Helpers
6
+ def self.extended(base)
7
+ base.send :include, Rhoconnect::Model::Helpers::FindDuplicatesOnUpdate
8
+ end
9
+
10
+ def validators
11
+ @validators ||= {}
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,85 @@
1
+ module Rhoconnect
2
+ module Model
3
+ module Helpers
4
+ module FindDuplicatesOnUpdate
5
+
6
+ def self.included(base)
7
+ base.extend Rhoconnect::Model::Helpers::FindDuplicatesOnUpdate::ClassMethods
8
+ end
9
+
10
+ def find_duplicates_on_update(options, invalid_meta, operation, operation_data, client_ids)
11
+ invalid_meta ||= {}
12
+ processed_ids = {}
13
+ processed_objs = {}
14
+ operation_data.each_with_index do |client_operation_data,index|
15
+ client_id = client_ids[index]
16
+ client_operation_data.each do |source_operation_entry|
17
+ source_id = source_operation_entry[0]
18
+ list_of_objs = source_operation_entry[1]
19
+ list_of_objs.each_with_index do |obj_entry, objindex|
20
+ key = obj_entry[0]
21
+ objvalue = obj_entry[1]
22
+
23
+ processed_objs[source_id] ||= {}
24
+ processed_source_objs = processed_objs[source_id]
25
+ obj_not_a_duplicate = true
26
+ if processed_source_objs.has_key? key
27
+ processed_records = processed_source_objs[key]
28
+ processed_records.each do |processed_record|
29
+ master_obj = processed_record[:value]
30
+ master_client_id = processed_record[:client_id]
31
+ master_queue_index = processed_record[:queue_index].to_i
32
+ master_obj_index = processed_record[:index].to_i
33
+
34
+ if master_obj == objvalue
35
+ obj_not_a_duplicate = false
36
+ if options[:raise_error]
37
+ invalid_meta[index] ||= {}
38
+ invalid_meta[index][source_id] ||= {}
39
+ invalid_meta[index][source_id][objindex] ||= {}
40
+ invalid_meta[index][source_id][objindex][:error] = "Error during #{operation}: object confict detected"
41
+ else
42
+ invalid_meta[index] ||= {}
43
+ invalid_meta[index][source_id] ||= {}
44
+ invalid_meta[index][source_id][objindex] ||= {}
45
+ invalid_meta[index][source_id][objindex][:duplicate_of] = true
46
+
47
+ invalid_meta[master_queue_index] ||= {}
48
+ invalid_meta[master_queue_index][source_id] ||= {}
49
+ invalid_meta[master_queue_index][source_id][master_obj_index] ||= {}
50
+ invalid_meta[master_queue_index][source_id][master_obj_index][:duplicates] ||= []
51
+ invalid_meta[master_queue_index][source_id][master_obj_index][:duplicates] << {:client_id => client_id, :key => key, :value => objvalue}
52
+ end
53
+ break
54
+ end
55
+ end
56
+ end
57
+ # objects are not equal - add to already processed
58
+ if obj_not_a_duplicate
59
+ processed_source_objs[key] ||= []
60
+ processed_source_objs[key] << {:value => objvalue, :client_id => client_id, :queue_index => index, :index => objindex}
61
+ end
62
+ end
63
+ end
64
+ end
65
+ if options[:handler] and invalid_meta.size > 0
66
+ proc = bind_handler :find_duplicates_on_update, options[:handler]
67
+ invalid_meta = proc.call options, invalid_meta, operation, operation_data, client_ids
68
+ end
69
+ invalid_meta
70
+ end
71
+
72
+ # methods that needs to be 'extended', not 'included'
73
+ module ClassMethods
74
+ def install_find_duplicates_on_update(options)
75
+ options ||= {}
76
+ options[:update] = true
77
+ @validators ||= {}
78
+ @validators[:find_duplicates_on_update] = options
79
+ options
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -9,7 +9,7 @@ module Rhoconnect
9
9
  def method_missing(method_name,*args)
10
10
  obj = Object.const_get(self.class.to_s)
11
11
  if obj.js_method_list.include? method_name.to_s
12
- package_and_publish(method_name,args)
12
+ self.class.package_and_publish(self,method_name,current_user,args)
13
13
  else
14
14
  log "METHOD #{method_name} NOT DEFINED IN JS MODEL #{self.class.to_s}"
15
15
  return "#{method_name} method not defined for #{self.class.to_s}"
@@ -68,49 +68,44 @@ module Rhoconnect
68
68
  rho_methods('storeBlob',blob)
69
69
  end
70
70
 
71
- private
71
+ def self.partition_name(user_id)
72
+ class_rho_methods('partitionName',{:user_id => user_id})
73
+ end
74
+
75
+ def self.class_rho_methods(name,args=nil)
76
+ if has_method? name
77
+ package_and_publish(self,name,nil,args)
78
+ else
79
+ send(name,args)
80
+ end
81
+ end
82
+
83
+ def self.has_method?(name)
84
+ self.js_method_list.include? name
85
+ end
72
86
 
73
87
  def rho_methods(name,args=nil)
74
- obj = Object.const_get(self.class.to_s)
75
- if obj.js_method_list.include? name
76
- package_and_publish(name,args)
88
+ if self.class.has_method? name
89
+ self.class.package_and_publish(self,name,self.current_user,args)
77
90
  else
78
- sup.send(name,args)
91
+ send(name,args)
79
92
  end
80
93
  end
81
94
 
82
- def package_and_publish(method_name,args=nil)
95
+ def self.package_and_publish(caller,method_name,user,args=nil)
83
96
  json = {
84
- :klss => self.class.actual_name,
97
+ :klss => self.actual_name,
85
98
  :function => method_name,
86
99
  :args => args,
87
- :user => current_user.login,
88
100
  :route => 'request'
89
101
  }
90
- NodeChannel.publish_channel_and_wait(json,self)
102
+ json[:user] = user.login if user
103
+ NodeChannel.publish_channel_and_wait(json,caller)
91
104
  end
92
105
  end
93
106
  end
94
107
  end
95
108
 
96
- #allows me to call super method by passing string
97
- class SuperProxy
98
- def initialize(obj)
99
- @obj = obj
100
- end
101
-
102
- def method_missing(meth, *args)
103
- @obj.class.superclass.superclass.instance_method(meth).bind(@obj).call(*args)
104
- end
105
- end
106
-
107
- class Object
108
- private
109
- def sup
110
- SuperProxy.new(self)
111
- end
112
- end
113
-
114
109
  class String
115
110
  def classify
116
111
  result = self.split("_").inject("") do |res,index|
@@ -31,17 +31,13 @@ module Rhoconnect
31
31
  @default_settings ||= {}
32
32
  @default_settings[setting] = value
33
33
  end
34
+ end
34
35
 
35
- # these methods will be called by the subclasses
36
- # to prevent double inclusion
37
- # of the base middleware
38
- # def reset_rc_base!
39
- # #@middleware_configured = true
40
- # end
41
-
42
- # def self.inherited(subclass)
43
- # subclass.reset_rc_base!
44
- # end
36
+ def self.paths(verb = nil)
37
+ @paths ||= {}
38
+ return @paths if verb.nil?
39
+ @paths[verb] ||= []
40
+ @paths[verb]
45
41
  end
46
42
 
47
43
  # Setup route and mimetype for bulk data downloads
@@ -56,10 +52,12 @@ module Rhoconnect
56
52
  extend Rhoconnect::Condition::ClientRequired
57
53
  extend Rhoconnect::Condition::Verbs
58
54
  extend Rhoconnect::Condition::VerifySuccess
55
+ extend Rhoconnect::Condition::AddParameter
59
56
 
60
57
  # RC Handlers
61
58
  include Rhoconnect::Handler::Query::ExecuteMethods
62
59
  include Rhoconnect::Handler::Changes::ExecuteMethods
60
+ register Rhoconnect::Handler::Changes::Hooks
63
61
  include Rhoconnect::Handler::Search::ExecuteMethods
64
62
  include Rhoconnect::Handler::PluginCallbacks::ExecuteMethods
65
63
  include Rhoconnect::Handler::Authenticate::ExecuteMethods
@@ -230,7 +228,10 @@ _INSTALL_ASYNC_GEMS
230
228
  rc_handler = options[:rc_handler]
231
229
  options.delete(:rc_handler)
232
230
  rc_handler_method = nil
233
- rc_handler_method = "execute_#{rc_handler}_handler".to_sym if rc_handler
231
+ if rc_handler
232
+ rc_handler_method = "execute_#{rc_handler}_handler"
233
+ invoke_hook(:handler_installed, self, rc_handler, verb, route_url, options)
234
+ end
234
235
  unless deprecated_route.nil?
235
236
  deprecated_urls = deprecated_route[:url].is_a?(String) ? [deprecated_route[:url]] : deprecated_route[:url]
236
237
  deprecated_urls.each do |deprecated_url|
@@ -245,8 +246,10 @@ _INSTALL_ASYNC_GEMS
245
246
  dep_info[:verb] = verb
246
247
  dep_info[:route_url] = route_url
247
248
 
248
- Rhoconnect::DefaultServer.registered_routes(d_verb)[deprecated_url] ||= {}
249
- Rhoconnect::DefaultServer.registered_routes(d_verb)[deprecated_url][self.name] = dep_info
249
+ #Rhoconnect::DefaultServer.paths[d_verb] ||= []
250
+ Rhoconnect::DefaultServer.paths(d_verb) << deprecated_url
251
+ Rhoconnect::DefaultServer.deprecated_routes(d_verb)[deprecated_url] ||= {}
252
+ Rhoconnect::DefaultServer.deprecated_routes(d_verb)[deprecated_url][self.name] = dep_info
250
253
  Rhoconnect::DefaultServer.send d_verb, deprecated_url, options do
251
254
  klass = nil
252
255
  req_verb = env['REQUEST_METHOD'].downcase.to_sym
@@ -254,7 +257,7 @@ _INSTALL_ASYNC_GEMS
254
257
  # retrieve controller-specific deprecation handler
255
258
  if params[:source_name]
256
259
  controller_name = "#{params[:source_name]}Controller"
257
- dep_info = Rhoconnect::DefaultServer.registered_routes(req_verb)[req_path][controller_name]
260
+ dep_info = Rhoconnect::DefaultServer.deprecated_routes(req_verb)[req_path][controller_name]
258
261
  if dep_info
259
262
  klass = dep_info[:klass]
260
263
  verb = dep_info[:verb]
@@ -270,6 +273,8 @@ _INSTALL_ASYNC_GEMS
270
273
 
271
274
  # turn block into UnboundMethod - so that we can bind it later with
272
275
  # particular Controller instance
276
+ #self.paths[verb] ||= []
277
+ self.paths(verb) << route_url
273
278
  route_handler = send(:generate_method, :route_handler, &block)
274
279
  route verb.to_s.upcase, route_url, options do
275
280
  execute_api_call(route_handler, rc_handler_method)
@@ -283,10 +288,10 @@ _INSTALL_ASYNC_GEMS
283
288
  helpers Rhoconnect::Handler::Helpers::BulkData
284
289
 
285
290
  # to prevent registering the same route several times
286
- def self.registered_routes(verb)
287
- @registered_routes ||= {}
288
- @registered_routes[verb] ||= {}
289
- @registered_routes[verb]
291
+ def self.deprecated_routes(verb)
292
+ @deprecated_routes ||= {}
293
+ @deprecated_routes[verb] ||= {}
294
+ @deprecated_routes[verb]
290
295
  end
291
296
 
292
297
  get '/' do
@@ -117,14 +117,7 @@ module Rhoconnect
117
117
  :metadata,
118
118
  :metadata_sha1,
119
119
  :schema,
120
- :schema_sha1,
121
- :create,
122
- :update,
123
- :delete])
124
- # we can not enforce valid doctypes at this point
125
- # because QUERY creates temporary md docs
126
- # TODO: re-work it to eliminate this obstacle
127
- #enforce_valid_doctypes=false
120
+ :schema_sha1])
128
121
 
129
122
  def initialize(fields)
130
123
  self.name = fields['name'] || fields[:name]
@@ -286,19 +279,19 @@ module Rhoconnect
286
279
 
287
280
  def flush_store_data
288
281
  delete_user_read_state
289
- # queues should be processed separately first
290
- [:create, :update, :delete].each do |doctype|
291
- flush_queue(doctype)
292
- end
293
- # then, all other doctypes
294
- self.class.valid_doctypes.each do |doctype|
295
- flush_data(doctype)
282
+ self.class.valid_doctypes.each do |docname, doctype|
283
+ case doctype
284
+ when :queue
285
+ flush_queue(docname)
286
+ when :document
287
+ flush_data(docname)
288
+ end
296
289
  end
297
290
  end
298
291
 
299
292
  def queue_docname(dockey)
300
293
  # currently, all queues are bound by user - not shared
301
- docname(dockey)
294
+ "#{self.class.class_prefix(self.class)}:#{self.app_id}:#{self.name}:#{dockey.to_s}"
302
295
  end
303
296
 
304
297
  # this data is not sharded
@@ -338,7 +331,7 @@ module Rhoconnect
338
331
  end
339
332
  end
340
333
 
341
- def push_queue(doctype,assoc_key, data={},append=false)
334
+ def push_queue(doctype,assoc_key, data=[],append=false)
342
335
  verify_doctype(doctype)
343
336
  lock_queue_doc(doctype) do |s|
344
337
  Store.get_store(0).put_zdata(s.queue_docname(doctype),assoc_key, data,append)