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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -0
- data/Gemfile.lock +152 -2
- data/app/controllers/jason/api_controller.rb +1 -1
- data/client/lib/JasonContext.d.ts +6 -1
- data/client/lib/JasonProvider.d.ts +2 -2
- data/client/lib/JasonProvider.js +5 -124
- data/client/lib/createJasonReducers.js +41 -3
- data/client/lib/createOptDis.js +0 -2
- data/client/lib/createPayloadHandler.d.ts +6 -1
- data/client/lib/createPayloadHandler.js +42 -54
- 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/index.d.ts +3 -2
- data/client/lib/pruneIdsMiddleware.d.ts +2 -0
- data/client/lib/pruneIdsMiddleware.js +26 -0
- data/client/lib/restClient.d.ts +2 -0
- data/client/lib/restClient.js +17 -0
- data/client/lib/useJason.d.ts +5 -0
- data/client/lib/useJason.js +99 -0
- data/client/lib/useJason.test.d.ts +1 -0
- data/client/lib/useJason.test.js +79 -0
- data/client/lib/useSub.js +1 -0
- data/client/package.json +4 -3
- data/client/src/JasonProvider.tsx +5 -123
- data/client/src/createJasonReducers.ts +49 -3
- data/client/src/createOptDis.ts +0 -2
- data/client/src/createPayloadHandler.ts +47 -63
- data/client/src/createServerActionQueue.test.ts +42 -0
- data/client/src/createServerActionQueue.ts +47 -0
- data/client/src/pruneIdsMiddleware.ts +24 -0
- data/client/src/restClient.ts +13 -0
- data/client/src/useJason.test.ts +81 -0
- data/client/src/useJason.ts +115 -0
- data/client/src/useSub.ts +1 -0
- data/client/yarn.lock +59 -3
- data/jason-rails.gemspec +4 -0
- data/lib/jason.rb +12 -0
- data/lib/jason/api_model.rb +2 -12
- data/lib/jason/channel.rb +43 -21
- data/lib/jason/lua_generator.rb +49 -0
- data/lib/jason/publisher.rb +76 -35
- data/lib/jason/publisher_old.rb +112 -0
- data/lib/jason/subscription.rb +322 -99
- data/lib/jason/subscription_old.rb +171 -0
- data/lib/jason/version.rb +1 -1
- 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
|
data/lib/jason/subscription.rb
CHANGED
@@ -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
|
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
|
16
|
-
|
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
|
20
|
-
|
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
|
25
|
-
|
26
|
-
|
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
|
-
|
34
|
+
|
35
|
+
subs
|
29
36
|
end
|
30
37
|
|
31
|
-
def
|
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
|
-
|
41
|
-
|
42
|
-
|
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
|
45
|
-
|
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
|
50
|
-
|
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
|
-
|
54
|
-
|
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
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
-
|
74
|
-
|
75
|
-
|
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
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
-
|
87
|
-
|
88
|
-
|
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
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
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
|
-
|
100
|
-
|
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
|
104
|
-
if
|
105
|
-
|
106
|
-
|
107
|
-
|
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
|
112
|
-
|
113
|
-
|
114
|
-
|
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
|
-
|
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
|
-
|
121
|
-
|
122
|
-
|
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
|
-
|
126
|
-
.
|
127
|
-
|
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
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
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
|
-
|
278
|
+
def ids(model_name = model)
|
279
|
+
$redis_jason.smembers("jason:subscriptions:#{id}:ids:#{model_name}")
|
280
|
+
end
|
139
281
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
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
|
-
|
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
|
-
|
151
|
-
return if result.blank?
|
349
|
+
return if instance_jsons.blank?
|
152
350
|
|
153
|
-
|
154
|
-
|
155
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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(
|
390
|
+
ActionCable.server.broadcast(channel, payload)
|
168
391
|
end
|
169
392
|
end
|