jason-rails 0.4.1 → 0.6.2
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.
- checksums.yaml +4 -4
- data/.gitignore +4 -1
- data/.ruby-version +1 -0
- data/Gemfile.lock +152 -2
- data/README.md +117 -5
- data/app/controllers/jason/api/pusher_controller.rb +15 -0
- data/app/controllers/jason/api_controller.rb +44 -2
- data/client/lib/JasonContext.d.ts +6 -1
- data/client/lib/JasonContext.js +4 -1
- data/client/lib/JasonProvider.d.ts +2 -2
- data/client/lib/JasonProvider.js +5 -124
- data/client/lib/createJasonReducers.js +48 -3
- data/client/lib/createOptDis.js +0 -2
- data/client/lib/createPayloadHandler.d.ts +9 -1
- data/client/lib/createPayloadHandler.js +47 -55
- data/client/lib/createServerActionQueue.d.ts +10 -0
- data/client/lib/createServerActionQueue.js +48 -0
- data/client/lib/createServerActionQueue.test.d.ts +1 -0
- data/client/lib/createServerActionQueue.test.js +37 -0
- data/client/lib/createTransportAdapter.d.ts +5 -0
- data/client/lib/createTransportAdapter.js +20 -0
- data/client/lib/index.d.ts +5 -2
- data/client/lib/index.js +3 -1
- data/client/lib/makeEager.js +2 -2
- data/client/lib/pruneIdsMiddleware.d.ts +2 -0
- data/client/lib/pruneIdsMiddleware.js +24 -0
- data/client/lib/restClient.d.ts +2 -0
- data/client/lib/restClient.js +17 -0
- data/client/lib/transportAdapters/actionCableAdapter.d.ts +5 -0
- data/client/lib/transportAdapters/actionCableAdapter.js +35 -0
- data/client/lib/transportAdapters/pusherAdapter.d.ts +5 -0
- data/client/lib/transportAdapters/pusherAdapter.js +68 -0
- data/client/lib/useJason.d.ts +5 -0
- data/client/lib/useJason.js +94 -0
- data/client/lib/useJason.test.d.ts +1 -0
- data/client/lib/useJason.test.js +85 -0
- data/client/lib/useSub.d.ts +1 -1
- data/client/lib/useSub.js +6 -3
- data/client/package.json +5 -3
- data/client/src/JasonContext.ts +4 -1
- data/client/src/JasonProvider.tsx +5 -123
- data/client/src/createJasonReducers.ts +56 -3
- data/client/src/createOptDis.ts +0 -2
- data/client/src/createPayloadHandler.ts +53 -64
- data/client/src/createServerActionQueue.test.ts +42 -0
- data/client/src/createServerActionQueue.ts +47 -0
- data/client/src/createTransportAdapter.ts +13 -0
- data/client/src/index.ts +3 -1
- data/client/src/makeEager.ts +2 -2
- data/client/src/pruneIdsMiddleware.ts +24 -0
- data/client/src/restClient.ts +14 -0
- data/client/src/transportAdapters/actionCableAdapter.ts +38 -0
- data/client/src/transportAdapters/pusherAdapter.ts +72 -0
- data/client/src/useJason.test.ts +87 -0
- data/client/src/useJason.ts +110 -0
- data/client/src/useSub.ts +6 -3
- data/client/yarn.lock +71 -3
- data/config/routes.rb +5 -1
- data/jason-rails.gemspec +4 -0
- data/lib/jason.rb +61 -1
- data/lib/jason/api_model.rb +2 -12
- data/lib/jason/broadcaster.rb +19 -0
- data/lib/jason/channel.rb +50 -21
- data/lib/jason/graph_helper.rb +165 -0
- data/lib/jason/includes_helper.rb +108 -0
- data/lib/jason/lua_generator.rb +71 -0
- data/lib/jason/publisher.rb +82 -37
- data/lib/jason/publisher_old.rb +112 -0
- data/lib/jason/subscription.rb +349 -97
- data/lib/jason/subscription_old.rb +171 -0
- data/lib/jason/version.rb +1 -1
- metadata +80 -3
data/lib/jason/subscription.rb
CHANGED
@@ -1,31 +1,317 @@
|
|
1
1
|
class Jason::Subscription
|
2
2
|
attr_accessor :id, :config
|
3
|
+
attr_reader :includes_helper, :graph_helper
|
3
4
|
|
4
5
|
def initialize(id: nil, config: nil)
|
5
6
|
if id
|
6
7
|
@id = id
|
7
|
-
raw_config = $redis_jason.hgetall("jason:subscriptions:#{id}").map { |k,v| [k, JSON.parse(v)] }.to_h
|
8
|
+
raw_config = $redis_jason.hgetall("jason:subscriptions:#{id}").map { |k,v| [k, JSON.parse(v)] }.to_h
|
9
|
+
raise "Subscription ID #{id} does not exist" if raw_config.blank?
|
8
10
|
set_config(raw_config)
|
9
11
|
else
|
10
|
-
@id = Digest::MD5.hexdigest(config.to_json)
|
12
|
+
@id = Digest::MD5.hexdigest(config.sort_by { |key| key }.to_h.to_json)
|
11
13
|
configure(config)
|
12
14
|
end
|
15
|
+
@includes_helper = Jason::IncludesHelper.new({ model => self.config['includes'] })
|
16
|
+
@graph_helper = Jason::GraphHelper.new(self.id, @includes_helper)
|
17
|
+
|
18
|
+
check_for_missing_keys
|
19
|
+
end
|
20
|
+
|
21
|
+
def broadcaster
|
22
|
+
@broadcaster ||= Jason::Broadcaster.new(channel)
|
23
|
+
end
|
24
|
+
|
25
|
+
def check_for_missing_keys
|
26
|
+
missing_keys = includes_helper.all_models - Jason.schema.keys.map(&:to_s)
|
27
|
+
if missing_keys.present?
|
28
|
+
raise "#{missing_keys.inspect} are not in the schema. Only models in the Jason schema can be subscribed."
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.upsert_by_config(model, conditions: {}, includes: {})
|
33
|
+
self.new(config: {
|
34
|
+
model: model,
|
35
|
+
conditions: conditions || {},
|
36
|
+
includes: includes || {}
|
37
|
+
})
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.find_by_id(id)
|
41
|
+
self.new(id: id)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.for_instance_with_child(model_name, id, child_model_name, include_all = true)
|
45
|
+
sub_ids = for_instance(model_name, id, include_all = true)
|
46
|
+
sub_ids.select do |sub_id|
|
47
|
+
find_by_id(sub_id).includes_helper.in_sub(model_name, child_model_name)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.for_instance(model_name, id, include_all = true)
|
52
|
+
subs = $redis_jason.smembers("jason:models:#{model_name}:#{id}:subscriptions")
|
53
|
+
if include_all
|
54
|
+
subs += $redis_jason.smembers("jason:models:#{model_name}:all:subscriptions")
|
55
|
+
end
|
56
|
+
|
57
|
+
subs
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.for_model(model_name)
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
# Find and update subscriptions affected by a model changing foreign key
|
65
|
+
# comment, comment_id, post, old_post_id, new_post_id
|
66
|
+
def self.update_ids(changed_model_name, changed_model_id, foreign_model_name, old_foreign_id, new_foreign_id)
|
67
|
+
# There are 4 cases to consider.
|
68
|
+
# changed_instance ---/--- foreign_instance
|
69
|
+
# \--+--- new_foreign_instance
|
70
|
+
#
|
71
|
+
# foreign instance can either be parent or child for a given subscription
|
72
|
+
# 1. Child swap/add: foreign is child
|
73
|
+
# 2. Stay in the family: foreign is parent + both old and new foreign instances are part of the sub
|
74
|
+
# 3. Join the family: foreign is parent + only new foreign instance are part of the sub
|
75
|
+
# 4. Leave the family: foreign is parent + only the old foreign instance is part of the sub
|
76
|
+
|
77
|
+
#########
|
78
|
+
# Subs where changed is parent
|
79
|
+
sub_ids = for_instance_with_child(changed_model_name, changed_model_id, foreign_model_name, true)
|
80
|
+
sub_ids.each do |sub_id|
|
81
|
+
subscription = find_by_id(sub_id)
|
82
|
+
|
83
|
+
# If foreign key has been nulled, nothing to add
|
84
|
+
add = new_foreign_id.present? ? [
|
85
|
+
{
|
86
|
+
model_names: [changed_model_name, foreign_model_name],
|
87
|
+
instance_ids: [[changed_model_id, new_foreign_id]]
|
88
|
+
},
|
89
|
+
# Add IDs of child models
|
90
|
+
subscription.load_ids_for_sub_models(foreign_model_name, new_foreign_id)
|
91
|
+
] : nil
|
92
|
+
|
93
|
+
id_changeset = subscription.graph_helper.apply_update({
|
94
|
+
remove: [{
|
95
|
+
model_names: [changed_model_name, foreign_model_name],
|
96
|
+
instance_ids: [[changed_model_id, old_foreign_id]]
|
97
|
+
}],
|
98
|
+
add: add
|
99
|
+
})
|
100
|
+
|
101
|
+
subscription.apply_id_changeset(id_changeset)
|
102
|
+
subscription.broadcast_id_changeset(id_changeset)
|
103
|
+
end
|
104
|
+
|
105
|
+
old_sub_ids = for_instance_with_child(foreign_model_name, old_foreign_id, changed_model_name, true)
|
106
|
+
new_sub_ids = for_instance_with_child(foreign_model_name, new_foreign_id, changed_model_name, true)
|
107
|
+
|
108
|
+
#########
|
109
|
+
# Subs where changed is child
|
110
|
+
# + parent in both old + new
|
111
|
+
# this is simple, only the edges need to change - no IDs can be changed
|
112
|
+
(old_sub_ids & new_sub_ids).each do |sub_id|
|
113
|
+
subscription = find_by_id(sub_id)
|
114
|
+
subscription.graph_helper.apply_update({
|
115
|
+
remove: [{
|
116
|
+
model_names: [changed_model_name, foreign_model_name],
|
117
|
+
instance_ids: [[changed_model_id, old_foreign_id]]
|
118
|
+
}],
|
119
|
+
add: [{
|
120
|
+
model_names: [changed_model_name, foreign_model_name],
|
121
|
+
instance_ids: [[changed_model_id, new_foreign_id]]
|
122
|
+
}]
|
123
|
+
})
|
124
|
+
end
|
125
|
+
|
126
|
+
#########
|
127
|
+
# Subs where changed is child
|
128
|
+
# + old parent wasn't in the sub, but new parent is
|
129
|
+
# IE the changed instance is joining the sub
|
130
|
+
# No edges are removed, just added
|
131
|
+
(new_sub_ids - old_sub_ids).each do |sub_id|
|
132
|
+
subscription = find_by_id(sub_id)
|
133
|
+
id_changeset = subscription.graph_helper.apply_update({
|
134
|
+
add: [
|
135
|
+
{
|
136
|
+
model_names: [changed_model_name, foreign_model_name],
|
137
|
+
instance_ids: [[changed_model_id, new_foreign_id]]
|
138
|
+
},
|
139
|
+
# Add IDs of child models
|
140
|
+
subscription.load_ids_for_sub_models(changed_model_name, changed_model_id)
|
141
|
+
]
|
142
|
+
})
|
143
|
+
|
144
|
+
subscription.apply_id_changeset(id_changeset)
|
145
|
+
subscription.broadcast_id_changeset(id_changeset)
|
146
|
+
end
|
147
|
+
|
148
|
+
#########
|
149
|
+
# --> Leaving the family
|
150
|
+
# Subs where changed is child
|
151
|
+
# + old parent was in the sub, but new parent isn't
|
152
|
+
# Just need to remove the link, orphan detection will do the rest
|
153
|
+
(old_sub_ids - new_sub_ids).each do |sub_id|
|
154
|
+
subscription = find_by_id(sub_id)
|
155
|
+
id_changeset = subscription.graph_helper.apply_update({
|
156
|
+
remove: [
|
157
|
+
{
|
158
|
+
model_names: [changed_model_name, foreign_model_name],
|
159
|
+
instance_ids: [[changed_model_id, old_foreign_id]]
|
160
|
+
}
|
161
|
+
]
|
162
|
+
})
|
163
|
+
subscription.apply_id_changeset(id_changeset)
|
164
|
+
subscription.broadcast_id_changeset(id_changeset)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def self.remove_ids(model_name, ids)
|
169
|
+
# td: finish this
|
170
|
+
ids.each do |instance_id|
|
171
|
+
for_instance(model_name, instance_id, false).each do |sub_id|
|
172
|
+
subscription = find_by_id(sub_id)
|
173
|
+
|
174
|
+
id_changeset = subscription.graph_helper.apply_remove_node("#{model_name}:#{instance_id}")
|
175
|
+
subscription.apply_id_changeset(id_changeset)
|
176
|
+
subscription.broadcast_id_changeset(id_changeset)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# Add ID to any _all_ subscriptions
|
182
|
+
def self.add_id(model_name, id)
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
def self.all
|
187
|
+
$redis_jason.smembers('jason:subscriptions').map { |id| Jason::Subscription.find_by_id(id) }
|
13
188
|
end
|
14
189
|
|
15
190
|
def set_config(raw_config)
|
16
|
-
@config = raw_config.
|
191
|
+
@config = raw_config.deep_stringify_keys.deep_transform_values { |v| v.is_a?(Symbol) ? v.to_s : v }
|
192
|
+
end
|
193
|
+
|
194
|
+
def clear_id(model_name, id, parent_model_name)
|
195
|
+
remove_ids(model_name, [id])
|
196
|
+
end
|
197
|
+
|
198
|
+
# Add IDs that aren't present
|
199
|
+
def commit_ids(model_name, ids)
|
200
|
+
$redis_jason.sadd("jason:subscriptions:#{id}:ids:#{model_name}", ids)
|
201
|
+
ids.each do |instance_id|
|
202
|
+
$redis_jason.sadd("jason:models:#{model_name}:#{instance_id}:subscriptions", id)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def remove_ids(model_name, ids)
|
207
|
+
$redis_jason.srem("jason:subscriptions:#{id}:ids:#{model_name}", ids)
|
208
|
+
ids.each do |instance_id|
|
209
|
+
$redis_jason.srem("jason:models:#{model_name}:#{instance_id}:subscriptions", id)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def apply_id_changeset(changeset)
|
214
|
+
changeset[:ids_to_add].each do |model_name, ids|
|
215
|
+
commit_ids(model_name, ids)
|
216
|
+
end
|
217
|
+
|
218
|
+
changeset[:ids_to_remove].each do |model_name, ids|
|
219
|
+
remove_ids(model_name, ids)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def broadcast_id_changeset(changeset)
|
224
|
+
changeset[:ids_to_add].each do |model_name, ids|
|
225
|
+
ids.each { |id| add(model_name, id) }
|
226
|
+
end
|
227
|
+
|
228
|
+
changeset[:ids_to_remove].each do |model_name, ids|
|
229
|
+
ids.each { |id| destroy(model_name, id) }
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
# Take a model name and IDs and return an edge set of all the models that appear and
|
234
|
+
# their instance IDs
|
235
|
+
def load_ids_for_sub_models(model_name, ids)
|
236
|
+
# Limitation: Same association can't appear twice
|
237
|
+
includes_tree = includes_helper.get_tree_for(model_name)
|
238
|
+
all_models = includes_helper.all_models(model_name)
|
239
|
+
|
240
|
+
relation = model_name.classify.constantize.all.eager_load(includes_tree)
|
241
|
+
|
242
|
+
if model_name == model
|
243
|
+
if conditions.blank?
|
244
|
+
$redis_jason.sadd("jason:models:#{model_name}:all:subscriptions", id)
|
245
|
+
all_models -= [model_name]
|
246
|
+
else
|
247
|
+
relation = relation.where(conditions)
|
248
|
+
end
|
249
|
+
else
|
250
|
+
raise "Must supply IDs for sub models" if ids.nil?
|
251
|
+
return if ids.blank?
|
252
|
+
relation = relation.where(id: ids)
|
253
|
+
end
|
254
|
+
|
255
|
+
pluck_args = all_models.map { |m| "#{m.pluralize}.id" }
|
256
|
+
instance_ids = relation.pluck(*pluck_args)
|
257
|
+
|
258
|
+
# pluck returns only a 1D array if only 1 arg passed
|
259
|
+
if all_models.size == 1
|
260
|
+
instance_ids = [instance_ids]
|
261
|
+
end
|
262
|
+
|
263
|
+
return { model_names: all_models, instance_ids: instance_ids }
|
264
|
+
end
|
265
|
+
|
266
|
+
# 'posts', [post#1, post#2,...]
|
267
|
+
def set_ids_for_sub_models(model_name = model, ids = nil, enforce: false)
|
268
|
+
edge_set = load_ids_for_sub_models(model_name, ids)
|
269
|
+
|
270
|
+
# Build the tree
|
271
|
+
id_changeset = graph_helper.apply_update({
|
272
|
+
add: [edge_set]
|
273
|
+
})
|
274
|
+
apply_id_changeset(id_changeset)
|
275
|
+
end
|
276
|
+
|
277
|
+
def clear_all_ids
|
278
|
+
includes_helper.all_models.each do |model_name|
|
279
|
+
if model_name == model && conditions.blank?
|
280
|
+
$redis_jason.srem("jason:models:#{model_name}:all:subscriptions", id)
|
281
|
+
end
|
282
|
+
|
283
|
+
ids = $redis_jason.smembers("jason:subscriptions:#{id}:ids:#{model_name}")
|
284
|
+
ids.each do |instance_id|
|
285
|
+
$redis_jason.srem("jason:models:#{model_name}:#{instance_id}:subscriptions", id)
|
286
|
+
end
|
287
|
+
$redis_jason.del("jason:subscriptions:#{id}:ids:#{model_name}")
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
def ids(model_name = model)
|
292
|
+
$redis_jason.smembers("jason:subscriptions:#{id}:ids:#{model_name}")
|
293
|
+
end
|
294
|
+
|
295
|
+
def model
|
296
|
+
@config['model']
|
297
|
+
end
|
298
|
+
|
299
|
+
def model_klass(model_name)
|
300
|
+
model_name.to_s.classify.constantize
|
301
|
+
end
|
302
|
+
|
303
|
+
def conditions
|
304
|
+
@config['conditions']
|
17
305
|
end
|
18
306
|
|
19
307
|
def configure(raw_config)
|
20
308
|
set_config(raw_config)
|
21
|
-
$redis_jason.
|
309
|
+
$redis_jason.sadd("jason:subscriptions", id)
|
310
|
+
$redis_jason.hmset("jason:subscriptions:#{id}", *config.map { |k,v| [k, v.to_json] }.flatten)
|
22
311
|
end
|
23
312
|
|
24
313
|
def destroy
|
25
|
-
|
26
|
-
$redis_jason.srem("jason:#{model.to_s.underscore}:subscriptions", id)
|
27
|
-
end
|
28
|
-
$redis_jason.del("jason:subscriptions:#{id}")
|
314
|
+
raise
|
29
315
|
end
|
30
316
|
|
31
317
|
def add_consumer(consumer_id)
|
@@ -33,8 +319,9 @@ class Jason::Subscription
|
|
33
319
|
$redis_jason.sadd("jason:subscriptions:#{id}:consumers", consumer_id)
|
34
320
|
$redis_jason.hset("jason:consumers", consumer_id, Time.now.utc)
|
35
321
|
|
36
|
-
|
37
|
-
|
322
|
+
if before_consumer_count == 0
|
323
|
+
set_ids_for_sub_models
|
324
|
+
end
|
38
325
|
end
|
39
326
|
|
40
327
|
def remove_consumer(consumer_id)
|
@@ -42,7 +329,7 @@ class Jason::Subscription
|
|
42
329
|
$redis_jason.hdel("jason:consumers", consumer_id)
|
43
330
|
|
44
331
|
if consumer_count == 0
|
45
|
-
|
332
|
+
clear_all_ids
|
46
333
|
end
|
47
334
|
end
|
48
335
|
|
@@ -51,119 +338,84 @@ class Jason::Subscription
|
|
51
338
|
end
|
52
339
|
|
53
340
|
def channel
|
54
|
-
"jason
|
341
|
+
"jason-#{id}"
|
55
342
|
end
|
56
343
|
|
57
|
-
def
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
klass.where(conditions).find_each(&:cache_json)
|
62
|
-
update(model)
|
63
|
-
end
|
344
|
+
def user_can_access?(user)
|
345
|
+
# td: implement the authorization logic here
|
346
|
+
return true if Jason.authorization_service.blank?
|
347
|
+
Jason.authorization_service.call(user, model, conditions, includes_helper.all_models - [model])
|
64
348
|
end
|
65
349
|
|
66
|
-
def
|
67
|
-
|
68
|
-
$redis_jason.hset("jason:#{model.to_s.underscore}:subscriptions", id, value.to_json)
|
69
|
-
update(model)
|
70
|
-
end
|
350
|
+
def get
|
351
|
+
includes_helper.all_models.map { |model_name| [model_name, get_for_model(model_name)] }.to_h
|
71
352
|
end
|
72
353
|
|
73
|
-
def
|
74
|
-
|
75
|
-
$redis_jason.
|
354
|
+
def get_for_model(model_name)
|
355
|
+
if $redis_jason.sismember("jason:models:#{model_name}:all:subscriptions", id)
|
356
|
+
instance_jsons_hash, idx = $redis_jason.multi do |r|
|
357
|
+
r.hgetall("jason:cache:#{model_name}")
|
358
|
+
r.get("jason:subscription:#{id}:#{model_name}:idx")
|
359
|
+
end
|
360
|
+
instance_jsons = instance_jsons_hash.values
|
361
|
+
else
|
362
|
+
instance_jsons, idx = Jason::LuaGenerator.new.get_payload(model_name, id)
|
76
363
|
end
|
77
|
-
end
|
78
364
|
|
79
|
-
|
80
|
-
|
81
|
-
klass = model.to_s.classify.constantize
|
82
|
-
klass.publish_all(klass.all) if klass.respond_to?(:publish_all)
|
365
|
+
payload = instance_jsons.map do |instance_json|
|
366
|
+
instance_json ? JSON.parse(instance_json) : {}
|
83
367
|
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def get(model)
|
87
|
-
value = JSON.parse($redis_jason.get("#{channel}:#{model}:value") || '[]')
|
88
|
-
idx = $redis_jason.get("#{channel}:#{model}:idx").to_i
|
89
368
|
|
90
369
|
{
|
91
370
|
type: 'payload',
|
371
|
+
model: model_name,
|
372
|
+
payload: payload,
|
92
373
|
md5Hash: id,
|
93
|
-
|
94
|
-
value: value,
|
95
|
-
idx: idx
|
374
|
+
idx: idx.to_i
|
96
375
|
}
|
97
376
|
end
|
98
377
|
|
99
|
-
def
|
100
|
-
|
101
|
-
|
378
|
+
def add(model_name, instance_id)
|
379
|
+
idx = $redis_jason.incr("jason:subscription:#{id}:#{model_name}:idx")
|
380
|
+
payload = JSON.parse($redis_jason.hget("jason:cache:#{model_name}", instance_id) || '{}')
|
102
381
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
382
|
+
payload = {
|
383
|
+
id: instance_id,
|
384
|
+
model: model_name,
|
385
|
+
payload: payload,
|
386
|
+
md5Hash: id,
|
387
|
+
idx: idx.to_i
|
388
|
+
}
|
110
389
|
|
111
|
-
|
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
|
115
|
-
else
|
116
|
-
$throttle_rate
|
117
|
-
end
|
390
|
+
broadcaster.broadcast(payload)
|
118
391
|
end
|
119
392
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
conditions = config[model]['conditions']
|
124
|
-
|
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'] }
|
129
|
-
|
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
|
136
|
-
end
|
137
|
-
|
138
|
-
value = deep_stringify(value)
|
393
|
+
def update(model_name, instance_id, payload, gidx)
|
394
|
+
idx = Jason::LuaGenerator.new.get_subscription(model_name, instance_id, id, gidx)
|
395
|
+
return if idx.blank?
|
139
396
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
end
|
148
|
-
LUA
|
149
|
-
|
150
|
-
result = $redis_jason.eval cmd, [], ["#{channel}:#{model}", value.to_json]
|
151
|
-
return if result.blank?
|
397
|
+
payload = {
|
398
|
+
id: instance_id,
|
399
|
+
model: model_name,
|
400
|
+
payload: payload,
|
401
|
+
md5Hash: id,
|
402
|
+
idx: idx.to_i
|
403
|
+
}
|
152
404
|
|
153
|
-
|
154
|
-
|
155
|
-
diff = get_diff(old_value, value)
|
405
|
+
broadcaster.broadcast(payload)
|
406
|
+
end
|
156
407
|
|
157
|
-
|
408
|
+
def destroy(model_name, instance_id)
|
409
|
+
idx = $redis_jason.incr("jason:subscription:#{id}:#{model_name}:idx")
|
158
410
|
|
159
411
|
payload = {
|
160
|
-
|
412
|
+
id: instance_id,
|
413
|
+
model: model_name,
|
414
|
+
destroy: true,
|
161
415
|
md5Hash: id,
|
162
|
-
|
163
|
-
idx: idx.to_i,
|
164
|
-
latency: ((end_time - start_time)*1000).round
|
416
|
+
idx: idx.to_i
|
165
417
|
}
|
166
418
|
|
167
|
-
|
419
|
+
broadcaster.broadcast(payload)
|
168
420
|
end
|
169
421
|
end
|