jason-rails 0.4.1 → 0.5.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -0
  3. data/Gemfile.lock +152 -2
  4. data/app/controllers/jason/api_controller.rb +1 -1
  5. data/client/lib/JasonContext.d.ts +6 -1
  6. data/client/lib/JasonProvider.d.ts +2 -2
  7. data/client/lib/JasonProvider.js +5 -124
  8. data/client/lib/createJasonReducers.js +41 -3
  9. data/client/lib/createOptDis.js +0 -2
  10. data/client/lib/createPayloadHandler.d.ts +6 -1
  11. data/client/lib/createPayloadHandler.js +42 -54
  12. data/client/lib/createServerActionQueue.d.ts +10 -0
  13. data/client/lib/createServerActionQueue.js +48 -0
  14. data/client/lib/createServerActionQueue.test.d.ts +1 -0
  15. data/client/lib/createServerActionQueue.test.js +37 -0
  16. data/client/lib/index.d.ts +3 -2
  17. data/client/lib/pruneIdsMiddleware.d.ts +2 -0
  18. data/client/lib/pruneIdsMiddleware.js +26 -0
  19. data/client/lib/restClient.d.ts +2 -0
  20. data/client/lib/restClient.js +17 -0
  21. data/client/lib/useJason.d.ts +5 -0
  22. data/client/lib/useJason.js +99 -0
  23. data/client/lib/useJason.test.d.ts +1 -0
  24. data/client/lib/useJason.test.js +79 -0
  25. data/client/lib/useSub.js +1 -0
  26. data/client/package.json +4 -3
  27. data/client/src/JasonProvider.tsx +5 -123
  28. data/client/src/createJasonReducers.ts +49 -3
  29. data/client/src/createOptDis.ts +0 -2
  30. data/client/src/createPayloadHandler.ts +47 -63
  31. data/client/src/createServerActionQueue.test.ts +42 -0
  32. data/client/src/createServerActionQueue.ts +47 -0
  33. data/client/src/pruneIdsMiddleware.ts +24 -0
  34. data/client/src/restClient.ts +13 -0
  35. data/client/src/useJason.test.ts +81 -0
  36. data/client/src/useJason.ts +115 -0
  37. data/client/src/useSub.ts +1 -0
  38. data/client/yarn.lock +59 -3
  39. data/jason-rails.gemspec +4 -0
  40. data/lib/jason.rb +12 -0
  41. data/lib/jason/api_model.rb +2 -12
  42. data/lib/jason/channel.rb +43 -21
  43. data/lib/jason/lua_generator.rb +49 -0
  44. data/lib/jason/publisher.rb +76 -35
  45. data/lib/jason/publisher_old.rb +112 -0
  46. data/lib/jason/subscription.rb +322 -99
  47. data/lib/jason/subscription_old.rb +171 -0
  48. data/lib/jason/version.rb +1 -1
  49. metadata +67 -3
@@ -0,0 +1,112 @@
1
+ module Jason::PublisherOld
2
+ extend ActiveSupport::Concern
3
+
4
+ def cache_json
5
+ as_json_config = api_model.as_json_config
6
+ scope = api_model.scope
7
+
8
+ if self.persisted? && (scope.blank? || self.class.unscoped.send(scope).exists?(self.id))
9
+ payload = self.reload.as_json(as_json_config)
10
+ $redis_jason.hset("jason:#{self.class.name.underscore}:cache", self.id, payload.to_json)
11
+ else
12
+ $redis_jason.hdel("jason:#{self.class.name.underscore}:cache", self.id)
13
+ end
14
+ end
15
+
16
+ def publish_json
17
+ cache_json
18
+ return if skip_publish_json
19
+
20
+ self.class.jason_subscriptions.each do |id, config_json|
21
+ config = JSON.parse(config_json)
22
+
23
+ if (config['conditions'] || {}).all? { |field, value| self.send(field) == value }
24
+ Jason::Subscription.new(id: id).update(self.class.name.underscore)
25
+ end
26
+ end
27
+ end
28
+
29
+ def publish_json_if_changed
30
+ subscribed_fields = api_model.subscribed_fields
31
+ publish_json if (self.previous_changes.keys.map(&:to_sym) & subscribed_fields).present? || !self.persisted?
32
+ end
33
+
34
+ class_methods do
35
+ def subscriptions
36
+ $redis_jason.hgetall("jason:#{self.name.underscore}:subscriptions")
37
+ end
38
+
39
+ def jason_subscriptions
40
+ $redis_jason.hgetall("jason:#{self.name.underscore}:subscriptions")
41
+ end
42
+
43
+ def publish_all(instances)
44
+ instances.each(&:cache_json)
45
+
46
+ subscriptions.each do |id, config_json|
47
+ Jason::Subscription.new(id: id).update(self.name.underscore)
48
+ end
49
+ end
50
+
51
+ def flush_cache
52
+ $redis_jason.del("jason:#{self.name.underscore}:cache")
53
+ end
54
+
55
+ def setup_json
56
+ self.after_initialize -> {
57
+ @api_model = Jason::ApiModel.new(self.class.name.underscore)
58
+ }
59
+ self.after_commit :publish_json_if_changed
60
+
61
+ include_models = Jason::ApiModel.new(self.name.underscore).include_models
62
+
63
+ include_models.map do |assoc|
64
+ puts assoc
65
+ reflection = self.reflect_on_association(assoc.to_sym)
66
+ reflection.klass.after_commit -> {
67
+ subscribed_fields = Jason::ApiModel.new(self.class.name.underscore).subscribed_fields
68
+ puts subscribed_fields.inspect
69
+
70
+ if (self.previous_changes.keys.map(&:to_sym) & subscribed_fields).present?
71
+ self.send(reflection.inverse_of.name)&.publish_json
72
+ end
73
+ }
74
+ end
75
+ end
76
+
77
+ def find_or_create_by_id(params)
78
+ object = find_by(id: params[:id])
79
+
80
+ if object
81
+ object.update(params)
82
+ elsif params[:hidden]
83
+ return false ## If an object is passed with hidden = true but didn't already exist, it's safe to never create it
84
+ else
85
+ object = create!(params)
86
+ end
87
+
88
+ object
89
+ end
90
+
91
+ def find_or_create_by_id!(params)
92
+ object = find_by(id: params[:id])
93
+
94
+ if object
95
+ object.update!(params)
96
+ elsif params[:hidden]
97
+ ## TODO: We're diverging from semantics of the Rails bang! methods here, which would normally either raise or return an object. Find a way to make this better.
98
+ return false ## If an object is passed with hidden = true but didn't already exist, it's safe to never create it
99
+ else
100
+ object = create!(params)
101
+ end
102
+
103
+ object
104
+ end
105
+ end
106
+
107
+ included do
108
+ attr_accessor :skip_publish_json, :api_model
109
+
110
+ setup_json
111
+ end
112
+ end
@@ -4,166 +4,389 @@ class Jason::Subscription
4
4
  def initialize(id: nil, config: nil)
5
5
  if id
6
6
  @id = id
7
- raw_config = $redis_jason.hgetall("jason:subscriptions:#{id}").map { |k,v| [k, JSON.parse(v)] }.to_h.with_indifferent_access
7
+ raw_config = $redis_jason.hgetall("jason:subscriptions:#{id}").map { |k,v| [k, JSON.parse(v)] }.to_h
8
8
  set_config(raw_config)
9
9
  else
10
- @id = Digest::MD5.hexdigest(config.to_json)
10
+ @id = Digest::MD5.hexdigest(config.sort_by { |key| key }.to_h.to_json)
11
+ pp config.sort_by { |key| key }.to_h.to_json
11
12
  configure(config)
12
13
  end
14
+ pp @id
13
15
  end
14
16
 
15
- def set_config(raw_config)
16
- @config = raw_config.with_indifferent_access.map { |k,v| [k.underscore.to_s, v] }.to_h
17
+ def self.upsert_by_config(model, conditions: {}, includes: {})
18
+ self.new(config: {
19
+ model: model,
20
+ conditions: conditions || {},
21
+ includes: includes || {}
22
+ })
17
23
  end
18
24
 
19
- def configure(raw_config)
20
- set_config(raw_config)
21
- $redis_jason.hmset("jason:subscriptions:#{id}", *config.map { |k,v| [k, v.to_json]}.flatten)
25
+ def self.find_by_id(id)
26
+ self.new(id: id)
22
27
  end
23
28
 
24
- def destroy
25
- config.each do |model, value|
26
- $redis_jason.srem("jason:#{model.to_s.underscore}:subscriptions", id)
29
+ def self.for_instance(model_name, id, include_all = true)
30
+ subs = $redis_jason.smembers("jason:models:#{model_name}:#{id}:subscriptions")
31
+ if include_all
32
+ subs += $redis_jason.smembers("jason:models:#{model_name}:all:subscriptions")
27
33
  end
28
- $redis_jason.del("jason:subscriptions:#{id}")
34
+
35
+ subs
29
36
  end
30
37
 
31
- def add_consumer(consumer_id)
32
- before_consumer_count = consumer_count
33
- $redis_jason.sadd("jason:subscriptions:#{id}:consumers", consumer_id)
34
- $redis_jason.hset("jason:consumers", consumer_id, Time.now.utc)
38
+ def self.for_model(model_name)
35
39
 
36
- add_subscriptions
37
- publish_all
38
40
  end
39
41
 
40
- def remove_consumer(consumer_id)
41
- $redis_jason.srem("jason:subscriptions:#{id}:consumers", consumer_id)
42
- $redis_jason.hdel("jason:consumers", consumer_id)
42
+ # Find and update subscriptions affected by a model changing foreign key
43
+ # comment, comment_id, post, old_post_id, new_post_id
44
+ def self.update_ids(model_name, id, parent_model_name, old_foreign_id, new_foreign_id)
45
+ # Check if this change means it needs to be removed
46
+ # First find subscriptions that reference this model
43
47
 
44
- if consumer_count == 0
45
- remove_subscriptions
48
+ if old_foreign_id
49
+ old_model_subscriptions = for_instance(parent_model_name, old_foreign_id, false)
50
+ new_model_subscriptions = for_instance(parent_model_name, new_foreign_id, false)
51
+ else
52
+ # If this is a new instance, we need to include _all_ subscriptions
53
+ old_model_subscriptions = []
54
+ new_model_subscriptions = for_instance(parent_model_name, new_foreign_id, true)
55
+ end
56
+
57
+ # To add
58
+ (new_model_subscriptions - old_model_subscriptions).each do |sub_id|
59
+ # add the current ID to the subscription, then add the tree below it
60
+ find_by_id(sub_id).set_id(model_name, id)
46
61
  end
62
+
63
+ # To remove
64
+ (old_model_subscriptions - new_model_subscriptions).each do |sub_id|
65
+ find_by_id(sub_id).remove_ids(model_name, [id])
66
+ end
67
+
68
+ # TODO changes to sub models - e.g. post -> comment -> user
47
69
  end
48
70
 
49
- def consumer_count
50
- $redis_jason.scard("jason:subscriptions:#{id}:consumers")
71
+ def self.remove_ids(model_name, ids)
72
+ ids.each do |instance_id|
73
+ for_instance(model_name, instance_id, false).each do |sub_id|
74
+ find_by_id(sub_id).remove_ids(model_name, [instance_id])
75
+ end
76
+ end
51
77
  end
52
78
 
53
- def channel
54
- "jason:#{id}"
79
+ # Add ID to any _all_ subscriptions
80
+ def self.add_id(model_name, id)
81
+
82
+ end
83
+
84
+ def self.all
85
+ $redis_jason.keys('jason:subscriptions:*')
86
+ end
87
+
88
+ def set_config(raw_config)
89
+ @config = raw_config.with_indifferent_access
90
+ end
91
+
92
+ # E.g. add comment#123, and then sub models
93
+ def set_id(model_name, id)
94
+ commit_ids(model_name, [id])
95
+ assoc_name = get_assoc_name(model_name)
96
+ set_ids_for_sub_models(assoc_name, [id])
97
+ end
98
+
99
+ def clear_id(model_name, id, parent_model_name)
100
+ remove_ids(model_name, [id])
55
101
  end
56
102
 
57
- def publish_all
58
- config.each do |model, model_config|
59
- klass = model.to_s.classify.constantize
60
- conditions = model_config['conditions'] || {}
61
- klass.where(conditions).find_each(&:cache_json)
62
- update(model)
103
+ # Set the instance IDs for the subscription
104
+ # Add an entry to the subscription list for each instance
105
+ def set_ids(assoc_name = model, referrer_model_name = nil, referrer_ids = nil, enforce: false)
106
+ model_name = assoc_name.to_s.singularize
107
+
108
+ if referrer_model_name.blank? && conditions.blank?
109
+ $redis_jason.sadd("jason:models:#{model_name}:all:subscriptions", id)
110
+ ids = model_klass(model_name).all.pluck(:id)
111
+ set_ids_for_sub_models(assoc_name, ids, enforce: enforce)
112
+ return
63
113
  end
114
+
115
+ if referrer_model_name.blank?
116
+ ids = model_klass(model_name).where(conditions).pluck(:id)
117
+ else
118
+ assoc = model_klass(referrer_model_name).reflect_on_association(assoc_name.to_sym)
119
+
120
+ if assoc.is_a?(ActiveRecord::Reflection::HasManyReflection)
121
+ ids = model_klass(model_name).where(assoc.foreign_key => referrer_ids).pluck(:id)
122
+ elsif assoc.is_a?(ActiveRecord::Reflection::BelongsToReflection)
123
+ ids = model_klass(referrer_model_name).where(id: referrer_ids).pluck(assoc.foreign_key)
124
+ end
125
+ end
126
+ return if ids.blank?
127
+
128
+ enforce ? enforce_ids(model_name, ids) : commit_ids(model_name, ids)
129
+ set_ids_for_sub_models(assoc_name, ids, enforce: enforce)
64
130
  end
65
131
 
66
- def add_subscriptions
67
- config.each do |model, value|
68
- $redis_jason.hset("jason:#{model.to_s.underscore}:subscriptions", id, value.to_json)
69
- update(model)
132
+ def refresh_ids(assoc_name = model, referrer_model_name = nil, referrer_ids)
133
+
134
+ end
135
+
136
+ # Add IDs that aren't present
137
+ def commit_ids(model_name, ids)
138
+ pp 'COMMIT'
139
+ pp model_name
140
+ pp ids
141
+ $redis_jason.sadd("jason:subscriptions:#{id}:ids:#{model_name}", ids)
142
+ ids.each do |instance_id|
143
+ $redis_jason.sadd("jason:models:#{model_name}:#{instance_id}:subscriptions", id)
70
144
  end
71
145
  end
72
146
 
73
- def remove_subscriptions
74
- config.each do |model, _|
75
- $redis_jason.hdel("jason:#{model.to_s.underscore}:subscriptions", id)
147
+ # Ensure IDs are _only_ the ones passed
148
+ def enforce_ids(model_name, ids)
149
+ old_ids = $redis_jason.smembers("jason:subscriptions:#{id}:ids:#{model_name}")
150
+
151
+ # Remove
152
+ $redis_jason.srem("jason:subscriptions:#{id}:ids:#{model_name}", (old_ids - ids))
153
+
154
+ (old_ids - ids).each do |instance_id|
155
+ $redis_jason.srem("jason:models:#{model_name}:#{instance_id}:subscriptions", id)
156
+ end
157
+
158
+ # Add
159
+ $redis_jason.sadd("jason:subscriptions:#{id}:ids:#{model_name}", (ids - old_ids))
160
+
161
+ (ids - old_ids).each do |instance_id|
162
+ $redis_jason.sadd("jason:models:#{model_name}:#{instance_id}:subscriptions", id)
76
163
  end
77
164
  end
78
165
 
79
- def self.publish_all
80
- JASON_API_MODEL.each do |model, _v|
81
- klass = model.to_s.classify.constantize
82
- klass.publish_all(klass.all) if klass.respond_to?(:publish_all)
166
+ def remove_ids(model_name, ids)
167
+ $redis_jason.srem("jason:subscriptions:#{id}:ids:#{model_name}", ids)
168
+ ids.each do |instance_id|
169
+ $redis_jason.srem("jason:models:#{model_name}:#{instance_id}:subscriptions", id)
83
170
  end
84
171
  end
85
172
 
86
- def get(model)
87
- value = JSON.parse($redis_jason.get("#{channel}:#{model}:value") || '[]')
88
- idx = $redis_jason.get("#{channel}:#{model}:idx").to_i
173
+ # 'posts', [post#1, post#2,...]
174
+ def set_ids_for_sub_models(assoc_name, ids, enforce: false)
175
+ model_name = assoc_name.to_s.singularize
176
+ # Limitation: Same association can't appear twice
177
+ includes_tree = get_tree_for(assoc_name)
89
178
 
90
- {
91
- type: 'payload',
92
- md5Hash: id,
93
- model: model,
94
- value: value,
95
- idx: idx
96
- }
179
+ if includes_tree.is_a?(Hash)
180
+ includes_tree.each do |assoc_name, includes_tree|
181
+ set_ids(assoc_name, model_name, ids, enforce: enforce)
182
+ end
183
+ # [:likes, :user]
184
+ elsif includes_tree.is_a?(Array)
185
+ includes_tree.each do |assoc_name|
186
+ set_ids(assoc_name, model_name, ids, enforce: enforce)
187
+ end
188
+ elsif includes_tree.is_a?(String)
189
+ set_ids(includes_tree, model_name, ids, enforce: enforce)
190
+ end
97
191
  end
98
192
 
99
- def get_diff(old_value, value)
100
- JsonDiff.generate(old_value, value)
193
+ # assoc could be plural or not, so need to scan both.
194
+ def get_assoc_name(model_name, haystack = includes)
195
+ return model_name if model_name == model
196
+
197
+ if haystack.is_a?(Hash)
198
+ haystack.each do |assoc_name, includes_tree|
199
+ if model_name.pluralize == assoc_name.to_s.pluralize
200
+ return assoc_name
201
+ else
202
+ found_assoc = get_assoc_name(model_name, includes_tree)
203
+ return found_assoc if found_assoc
204
+ end
205
+ end
206
+ elsif haystack.is_a?(Array)
207
+ haystack.each do |assoc_name|
208
+ if model_name.pluralize == assoc_name.to_s.pluralize
209
+ return assoc_name
210
+ end
211
+ end
212
+ else
213
+ if model_name.pluralize == haystack.to_s.pluralize
214
+ return haystack
215
+ end
216
+ end
217
+
218
+ return nil
101
219
  end
102
220
 
103
- def deep_stringify(value)
104
- if value.is_a?(Hash)
105
- value.deep_stringify_keys
106
- elsif value.is_a?(Array)
107
- value.map { |x| x.deep_stringify_keys }
221
+ def get_tree_for(needle, assoc_name = nil, haystack = includes)
222
+ return includes if needle == model
223
+ return haystack if needle.to_s == assoc_name.to_s
224
+
225
+ if haystack.is_a?(Hash)
226
+ haystack.each do |assoc_name, includes_tree|
227
+ found_haystack = get_tree_for(needle, assoc_name, includes_tree)
228
+ return found_haystack if found_haystack
229
+ end
108
230
  end
231
+
232
+ return nil
109
233
  end
110
234
 
111
- def get_throttle
112
- if !$throttle_rate || !$throttle_timeout || Time.now.utc > $throttle_timeout
113
- $throttle_timeout = Time.now.utc + 5.seconds
114
- $throttle_rate = ($redis_jason.get('global_throttle_rate') || 0).to_i
235
+ def all_models(tree = includes)
236
+ sub_models = if tree.is_a?(Hash)
237
+ tree.map do |k,v|
238
+ [k, all_models(v)]
239
+ end
115
240
  else
116
- $throttle_rate
241
+ tree
117
242
  end
243
+
244
+ pp ([model] + [sub_models]).flatten.uniq.map(&:to_s).map(&:singularize)
245
+ ([model] + [sub_models]).flatten.uniq.map(&:to_s).map(&:singularize)
118
246
  end
119
247
 
120
- # Atomically update and return patch
121
- def update(model)
122
- start_time = Time.now.utc
123
- conditions = config[model]['conditions']
248
+ def clear_all_ids(assoc_name = model)
249
+ model_name = assoc_name.to_s.singularize
250
+ includes_tree = model_name == model ? includes : get_tree_for(assoc_name)
124
251
 
125
- value = $redis_jason.hgetall("jason:#{model}:cache")
126
- .values.map { |v| JSON.parse(v) }
127
- .select { |v| (conditions || {}).all? { |field, value| v[field] == value } }
128
- .sort_by { |v| v['id'] }
252
+ if model_name == model && conditions.blank?
253
+ $redis_jason.srem("jason:models:#{model_name}:all:subscriptions", id)
254
+ end
129
255
 
130
- # lfsa = last finished, started at
131
- # If another job that started after this one, finished before this one, skip sending this state update
132
- if Time.parse($redis_jason.get("jason:#{channel}:lfsa") || '1970-01-01 00:00:00 UTC') < start_time
133
- $redis_jason.set("jason:#{channel}:lfsa", start_time)
134
- else
135
- return
256
+ ids = $redis_jason.smembers("jason:subscriptions:#{id}:ids:#{model_name}")
257
+ ids.each do |instance_id|
258
+ $redis_jason.srem("jason:models:#{model_name}:#{instance_id}:subscriptions", id)
259
+ end
260
+ $redis_jason.del("jason:subscriptions:#{id}:ids:#{model_name}")
261
+
262
+ # Recursively clear IDs
263
+ # { comments: [:like] }
264
+ if includes_tree.is_a?(Hash)
265
+ includes_tree.each do |assoc_name, includes_tree|
266
+ clear_all_ids(assoc_name)
267
+ end
268
+ # [:likes, :user]
269
+ elsif includes_tree.is_a?(Array)
270
+ includes_tree.each do |assoc_name|
271
+ clear_all_ids(assoc_name)
272
+ end
273
+ elsif includes_tree.is_a?(String)
274
+ clear_all_ids(includes_tree)
136
275
  end
276
+ end
137
277
 
138
- value = deep_stringify(value)
278
+ def ids(model_name = model)
279
+ $redis_jason.smembers("jason:subscriptions:#{id}:ids:#{model_name}")
280
+ end
139
281
 
140
- # If value has changed, return old value and new idx. Otherwise do nothing.
141
- cmd = <<~LUA
142
- local old_val=redis.call('get', ARGV[1] .. ':value')
143
- if old_val ~= ARGV[2] then
144
- redis.call('set', ARGV[1] .. ':value', ARGV[2])
145
- local new_idx = redis.call('incr', ARGV[1] .. ':idx')
146
- return { new_idx, old_val }
282
+ def model
283
+ @config['model']
284
+ end
285
+
286
+ def model_klass(model_name)
287
+ model_name.to_s.classify.constantize
288
+ end
289
+
290
+ def conditions
291
+ @config['conditions']
292
+ end
293
+
294
+ def includes
295
+ @config['includes']
296
+ end
297
+
298
+ def configure(raw_config)
299
+ set_config(raw_config)
300
+ $redis_jason.hmset("jason:subscriptions:#{id}", *config.map { |k,v| [k, v.to_json] }.flatten)
301
+ end
302
+
303
+ def destroy
304
+ raise
305
+ end
306
+
307
+ def add_consumer(consumer_id)
308
+ before_consumer_count = consumer_count
309
+ $redis_jason.sadd("jason:subscriptions:#{id}:consumers", consumer_id)
310
+ $redis_jason.hset("jason:consumers", consumer_id, Time.now.utc)
311
+
312
+ if before_consumer_count == 0
313
+ set_ids
314
+ end
315
+ end
316
+
317
+ def remove_consumer(consumer_id)
318
+ $redis_jason.srem("jason:subscriptions:#{id}:consumers", consumer_id)
319
+ $redis_jason.hdel("jason:consumers", consumer_id)
320
+
321
+ if consumer_count == 0
322
+ clear_all_ids
323
+ end
324
+ end
325
+
326
+ def consumer_count
327
+ $redis_jason.scard("jason:subscriptions:#{id}:consumers")
328
+ end
329
+
330
+ def channel
331
+ "jason:#{id}"
332
+ end
333
+
334
+ def get
335
+ all_models.map { |model_name| get_for_model(model_name) }
336
+ end
337
+
338
+ def get_for_model(model_name)
339
+ if $redis_jason.sismember("jason:models:#{model_name}:all:subscriptions", id)
340
+ instance_jsons_hash, idx = $redis_jason.multi do |r|
341
+ r.hgetall("jason:cache:#{model_name}")
342
+ r.get("jason:subscription:#{id}:#{model_name}:idx")
147
343
  end
148
- LUA
344
+ instance_jsons = instance_jsons_hash.values
345
+ else
346
+ instance_jsons, idx = Jason::LuaGenerator.new.get_payload(model_name, id)
347
+ end
149
348
 
150
- result = $redis_jason.eval cmd, [], ["#{channel}:#{model}", value.to_json]
151
- return if result.blank?
349
+ return if instance_jsons.blank?
152
350
 
153
- idx = result[0]
154
- old_value = JSON.parse(result[1] || '[]')
155
- diff = get_diff(old_value, value)
351
+ payload = instance_jsons.map do |instance_json|
352
+ instance_json ? JSON.parse(instance_json) : {}
353
+ end
354
+
355
+ {
356
+ type: 'payload',
357
+ model: model_name,
358
+ payload: payload,
359
+ md5Hash: id,
360
+ idx: idx.to_i
361
+ }
362
+ end
156
363
 
157
- end_time = Time.now.utc
364
+ def update(model_name, instance_id, payload, gidx)
365
+ idx = Jason::LuaGenerator.new.get_subscription(model_name, instance_id, id, gidx)
366
+ return if idx.blank?
158
367
 
159
368
  payload = {
160
- model: model,
369
+ id: instance_id,
370
+ model: model_name,
371
+ payload: payload,
372
+ md5Hash: id,
373
+ idx: idx.to_i
374
+ }
375
+
376
+ ActionCable.server.broadcast(channel, payload)
377
+ end
378
+
379
+ def destroy(model_name, instance_id)
380
+ idx = $redis_jason.incr("jason:subscription:#{id}:#{model_name}idx")
381
+
382
+ payload = {
383
+ id: instance_id,
384
+ model: model_name,
385
+ destroy: true,
161
386
  md5Hash: id,
162
- diff: diff,
163
- idx: idx.to_i,
164
- latency: ((end_time - start_time)*1000).round
387
+ idx: idx.to_i
165
388
  }
166
389
 
167
- ActionCable.server.broadcast("jason:#{id}", payload)
390
+ ActionCable.server.broadcast(channel, payload)
168
391
  end
169
392
  end