jason-rails 0.6.4 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +38 -0
- data/Gemfile.lock +7 -2
- data/README.md +4 -12
- data/app/controllers/jason/{api_controller.rb → jason_controller.rb} +1 -1
- data/app/controllers/jason/{api/pusher_controller.rb → pusher_controller.rb} +1 -1
- data/app/workers/jason/outbound_message_queue_worker.rb +21 -0
- data/client/lib/addRelations.d.ts +1 -0
- data/client/lib/addRelations.js +39 -0
- data/client/lib/createJasonReducers.js +4 -2
- data/client/lib/createOptDis.d.ts +1 -1
- data/client/lib/createOptDis.js +9 -8
- data/client/lib/createServerActionQueue.d.ts +3 -2
- data/client/lib/createServerActionQueue.js +32 -6
- data/client/lib/createServerActionQueue.test.js +61 -6
- data/client/lib/createThenable.d.ts +1 -0
- data/client/lib/createThenable.js +5 -0
- data/client/lib/transportAdapters/actionCableAdapter.js +24 -4
- data/client/lib/transportAdapters/pusherAdapter.js +1 -1
- data/client/lib/useDraft.d.ts +1 -0
- data/client/lib/useDraft.js +13 -0
- data/client/lib/useEager.d.ts +1 -1
- data/client/lib/useEager.js +10 -5
- data/client/lib/useJason.js +2 -4
- data/client/package.json +1 -1
- data/client/src/addRelations.ts +33 -0
- data/client/src/createJasonReducers.ts +4 -2
- data/client/src/createOptDis.ts +10 -8
- data/client/src/createServerActionQueue.test.ts +60 -6
- data/client/src/createServerActionQueue.ts +41 -6
- data/client/src/transportAdapters/actionCableAdapter.ts +24 -5
- data/client/src/transportAdapters/pusherAdapter.ts +1 -2
- data/client/src/useDraft.ts +17 -0
- data/client/src/useEager.ts +9 -6
- data/client/src/useJason.ts +1 -4
- data/config/routes.rb +6 -6
- data/jason-rails.gemspec +1 -0
- data/lib/jason.rb +7 -3
- data/lib/jason/api_model.rb +0 -4
- data/lib/jason/broadcaster.rb +2 -1
- data/lib/jason/channel.rb +0 -7
- data/lib/jason/conditions_matcher.rb +88 -0
- data/lib/jason/consistency_checker.rb +61 -0
- data/lib/jason/graph_helper.rb +19 -4
- data/lib/jason/publisher.rb +40 -7
- data/lib/jason/subscription.rb +77 -17
- data/lib/jason/version.rb +1 -1
- metadata +30 -5
- data/client/src/makeEager.ts +0 -46
@@ -1,11 +1,10 @@
|
|
1
1
|
import Pusher from 'pusher-js'
|
2
|
-
import { createConsumer } from "@rails/actioncable"
|
3
2
|
import restClient from '../restClient'
|
4
3
|
import { v4 as uuidv4 } from 'uuid'
|
5
4
|
import _ from 'lodash'
|
6
5
|
|
7
6
|
export default function pusherAdapter(jasonConfig, handlePayload, dispatch) {
|
8
|
-
|
7
|
+
const consumerId = uuidv4()
|
9
8
|
|
10
9
|
const { pusherKey, pusherRegion, pusherChannelPrefix } = jasonConfig
|
11
10
|
const pusher = new Pusher(pusherKey, {
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import _ from 'lodash'
|
2
|
+
import { useSelector } from 'react-redux'
|
3
|
+
import addRelations from './addRelations'
|
4
|
+
|
5
|
+
/* Can be called as
|
6
|
+
useDraft() => draft object for making updates
|
7
|
+
useDraft('entity', id) => returns [draft, object]
|
8
|
+
useDraft('entity', id, relations) => returns [draft, objectWithEmbeddedRelations]
|
9
|
+
*/
|
10
|
+
|
11
|
+
export default function useDraft(entity, id, relations = []) {
|
12
|
+
// const entityDraft =`${entity}Draft`
|
13
|
+
// const object = { ...s[entityDraft].entities[String(id)] }
|
14
|
+
|
15
|
+
// return useSelector(s => addRelations(s, object, entity, relations, 'Draft'), _.isEqual)
|
16
|
+
}
|
17
|
+
|
data/client/src/useEager.ts
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
import
|
2
|
-
import {
|
1
|
+
import _ from 'lodash'
|
2
|
+
import { useSelector } from 'react-redux'
|
3
|
+
import addRelations from './addRelations'
|
3
4
|
|
4
|
-
export default function useEager(entity, id =
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
export default function useEager(entity: string, id = '', relations = [] as any) {
|
6
|
+
if (id) {
|
7
|
+
return useSelector(s => addRelations(s, { ...s[entity].entities[String(id)] }, entity, relations), _.isEqual)
|
8
|
+
} else {
|
9
|
+
return useSelector(s => addRelations(s, _.values(s[entity].entities), entity, relations), _.isEqual)
|
10
|
+
}
|
8
11
|
}
|
9
12
|
|
data/client/src/useJason.ts
CHANGED
@@ -9,7 +9,6 @@ import createTransportAdapater from './createTransportAdapter'
|
|
9
9
|
|
10
10
|
import { createEntityAdapter, createSlice, createReducer, configureStore } from '@reduxjs/toolkit'
|
11
11
|
|
12
|
-
import makeEager from './makeEager'
|
13
12
|
import { camelizeKeys } from 'humps'
|
14
13
|
import md5 from 'blueimp-md5'
|
15
14
|
import _ from 'lodash'
|
@@ -41,7 +40,6 @@ export default function useJason({ reducers, middleware = [], extraActions }: {
|
|
41
40
|
|
42
41
|
const optDis = createOptDis(schema, dispatch, restClient, serverActionQueue)
|
43
42
|
const actions = createActions(schema, store, restClient, optDis, extraActions)
|
44
|
-
const eager = makeEager(schema)
|
45
43
|
|
46
44
|
let payloadHandlers = {}
|
47
45
|
let configs = {}
|
@@ -90,7 +88,7 @@ export default function useJason({ reducers, middleware = [], extraActions }: {
|
|
90
88
|
function removeSubscription(config) {
|
91
89
|
transportAdapter.removeSubscription(config)
|
92
90
|
const md5Hash = md5(JSON.stringify(config))
|
93
|
-
payloadHandlers[md5Hash]
|
91
|
+
payloadHandlers[md5Hash]?.tearDown() // Race condition where component mounts then unmounts quickly
|
94
92
|
delete payloadHandlers[md5Hash]
|
95
93
|
delete configs[md5Hash]
|
96
94
|
delete subOptions[md5Hash]
|
@@ -99,7 +97,6 @@ export default function useJason({ reducers, middleware = [], extraActions }: {
|
|
99
97
|
setValue({
|
100
98
|
actions: actions,
|
101
99
|
subscribe: createSubscription,
|
102
|
-
eager,
|
103
100
|
handlePayload
|
104
101
|
})
|
105
102
|
setStore(store)
|
data/config/routes.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
Jason::Engine.routes.draw do
|
2
|
-
get '/api/config', to: '
|
3
|
-
post '/api/action', to: '
|
4
|
-
post '/api/create_subscription', to: '
|
5
|
-
post '/api/remove_subscription', to: '
|
6
|
-
post '/api/get_payload', to: '
|
7
|
-
post '/api/pusher/auth', to: '
|
2
|
+
get '/api/config', to: 'jason#configuration'
|
3
|
+
post '/api/action', to: 'jason#action'
|
4
|
+
post '/api/create_subscription', to: 'jason#create_subscription'
|
5
|
+
post '/api/remove_subscription', to: 'jason#remove_subscription'
|
6
|
+
post '/api/get_payload', to: 'jason#get_payload'
|
7
|
+
post '/api/pusher/auth', to: 'pusher#auth'
|
8
8
|
end
|
data/jason-rails.gemspec
CHANGED
data/lib/jason.rb
CHANGED
@@ -12,6 +12,8 @@ require 'jason/engine'
|
|
12
12
|
require 'jason/lua_generator'
|
13
13
|
require 'jason/includes_helper'
|
14
14
|
require 'jason/graph_helper'
|
15
|
+
require 'jason/conditions_matcher'
|
16
|
+
require 'jason/consistency_checker'
|
15
17
|
|
16
18
|
module Jason
|
17
19
|
class Error < StandardError; end
|
@@ -24,20 +26,24 @@ module Jason
|
|
24
26
|
self.mattr_accessor :pusher_region
|
25
27
|
self.mattr_accessor :pusher_channel_prefix
|
26
28
|
self.mattr_accessor :authorization_service
|
29
|
+
self.mattr_accessor :sidekiq_queue
|
27
30
|
|
28
31
|
self.schema = {}
|
29
32
|
self.transport_service = :action_cable
|
30
33
|
self.pusher_region = 'eu'
|
31
34
|
self.pusher_channel_prefix = 'jason'
|
35
|
+
self.sidekiq_queue = 'default'
|
32
36
|
|
33
37
|
def self.init
|
38
|
+
# Don't run in AR migration / generator etc.
|
39
|
+
return if $PROGRAM_NAME == '-e' || ActiveRecord::Base.connection.migration_context.needs_migration?
|
40
|
+
|
34
41
|
# Check if the schema has changed since last time app was started. If so, do some work to ensure cache contains the correct data
|
35
42
|
got_lock = $redis_jason.set('jason:schema:lock', nx: true, ex: 3600) # Basic lock mechanism for multi-process environments
|
36
43
|
return if !got_lock
|
37
44
|
|
38
45
|
previous_schema = JSON.parse($redis_jason.get('jason:last_schema') || '{}')
|
39
46
|
current_schema = Jason.schema.deep_stringify_keys.deep_transform_values { |v| v.is_a?(Symbol) ? v.to_s : v }
|
40
|
-
pp current_schema
|
41
47
|
current_schema.each do |model, config|
|
42
48
|
if config != previous_schema[model]
|
43
49
|
puts "Config changed for #{model}"
|
@@ -52,8 +58,6 @@ module Jason
|
|
52
58
|
$redis_jason.set('jason:last_schema', current_schema.to_json)
|
53
59
|
ensure
|
54
60
|
$redis_jason.del('jason:schema:lock')
|
55
|
-
|
56
|
-
previous_config = 'test'
|
57
61
|
end
|
58
62
|
|
59
63
|
|
data/lib/jason/api_model.rb
CHANGED
@@ -36,11 +36,7 @@ class Jason::ApiModel
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def permit(params)
|
39
|
-
pp self
|
40
|
-
pp params
|
41
39
|
params = params.require(:payload).permit(allowed_params).tap do |allowed|
|
42
|
-
pp "ALLOWED"
|
43
|
-
pp allowed
|
44
40
|
allowed_object_params.each do |key|
|
45
41
|
allowed[key] = params[:payload][key].to_unsafe_h if params[:payload][key]
|
46
42
|
end
|
data/lib/jason/broadcaster.rb
CHANGED
@@ -13,7 +13,8 @@ class Jason::Broadcaster
|
|
13
13
|
if Jason.transport_service == :action_cable
|
14
14
|
ActionCable.server.broadcast(channel, message)
|
15
15
|
elsif Jason.transport_service == :pusher
|
16
|
-
|
16
|
+
$redis_jason.rpush("jason:outbound_message_queue", { channel: pusher_channel_name, name: 'changed', data: message }.to_json)
|
17
|
+
Jason::OutboundMessageQueueWorker.perform_async
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
data/lib/jason/channel.rb
CHANGED
@@ -12,7 +12,6 @@ class Jason::Channel < ActionCable::Channel::Base
|
|
12
12
|
private
|
13
13
|
|
14
14
|
def handle_message(message)
|
15
|
-
pp message['createSubscription']
|
16
15
|
@subscriptions ||= []
|
17
16
|
|
18
17
|
begin # ActionCable swallows errors in this message - ensure they're output to logs.
|
@@ -38,18 +37,12 @@ class Jason::Channel < ActionCable::Channel::Base
|
|
38
37
|
|
39
38
|
subscriptions.push(subscription)
|
40
39
|
subscription.add_consumer(identifier)
|
41
|
-
subscription.get.each do |payload|
|
42
|
-
pp payload
|
43
|
-
transmit(payload) if payload.present?
|
44
|
-
end
|
45
40
|
end
|
46
41
|
|
47
42
|
def remove_subscription(config)
|
48
43
|
subscription = Jason::Subscription.upsert_by_config(config['model'], conditions: config['conditions'], includes: config['includes'])
|
49
44
|
subscriptions.reject! { |s| s.id == subscription.id }
|
50
45
|
subscription.remove_consumer(identifier)
|
51
|
-
|
52
|
-
# TODO Stop streams
|
53
46
|
end
|
54
47
|
|
55
48
|
def get_payload(config, force_refresh = false)
|
@@ -0,0 +1,88 @@
|
|
1
|
+
class Jason::ConditionsMatcher
|
2
|
+
attr_reader :klass
|
3
|
+
|
4
|
+
def initialize(klass)
|
5
|
+
@klass = klass
|
6
|
+
end
|
7
|
+
|
8
|
+
# key, rules = 'post_id', 123
|
9
|
+
# key, rules = 'post_id', { 'value': [123,C456], 'type': 'between' }
|
10
|
+
# key, rules = 'post_id', { 'value': [123,456], 'type': 'between', 'not': true }
|
11
|
+
# key, rules = 'post_id', { 'value': 123, 'type': 'equals', 'not': true }
|
12
|
+
def test_match(key, rules, previous_changes)
|
13
|
+
return nil if !previous_changes.keys.include?(key)
|
14
|
+
|
15
|
+
if rules.is_a?(Hash)
|
16
|
+
matches = false
|
17
|
+
value = convert_to_datatype(key, rules['value'])
|
18
|
+
|
19
|
+
if rules['type'] == 'equals'
|
20
|
+
matches = previous_changes[key][1] == value
|
21
|
+
elsif rules['type'] == 'between'
|
22
|
+
matches = (value[0]..value[1]).cover?(previous_changes[key][1])
|
23
|
+
else
|
24
|
+
raise "Unrecognized rule type #{rules['type']}"
|
25
|
+
end
|
26
|
+
|
27
|
+
if rules['not']
|
28
|
+
return !matches
|
29
|
+
else
|
30
|
+
return matches
|
31
|
+
end
|
32
|
+
|
33
|
+
elsif rules.is_a?(Array)
|
34
|
+
value = convert_to_datatype(key, rules)
|
35
|
+
return previous_changes[key][1].includes?(value)
|
36
|
+
else
|
37
|
+
value = convert_to_datatype(key, rules)
|
38
|
+
return previous_changes[key][1] == value
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# conditions = { 'post_id' => 123, 'created_at' => { 'type' => 'between', 'value' => ['2020-01-01', '2020-01-02'] } }
|
43
|
+
def apply_conditions(relation, conditions)
|
44
|
+
conditions.each do |key, rules|
|
45
|
+
relation = apply_condition(relation, key, rules)
|
46
|
+
end
|
47
|
+
|
48
|
+
relation
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def apply_condition(relation, key, rules)
|
54
|
+
if rules.is_a?(Hash)
|
55
|
+
value = convert_to_datatype(key, rules['value'])
|
56
|
+
|
57
|
+
if rules['type'] == 'equals'
|
58
|
+
arg = { key => value }
|
59
|
+
elsif rules['type'] == 'between'
|
60
|
+
arg = { key => value[0]..value[1] }
|
61
|
+
else
|
62
|
+
raise "Unrecognized rule type #{rules['type']}"
|
63
|
+
end
|
64
|
+
|
65
|
+
if rules['not']
|
66
|
+
return relation.where.not(arg)
|
67
|
+
else
|
68
|
+
return relation.where(arg)
|
69
|
+
end
|
70
|
+
else
|
71
|
+
value = convert_to_datatype(key, rules)
|
72
|
+
return relation.where({ key => value })
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def convert_to_datatype(key, value)
|
77
|
+
datatype = klass.type_for_attribute(key).type
|
78
|
+
if datatype == :datetime || datatype == :date
|
79
|
+
if value.is_a?(Array)
|
80
|
+
value.map { |v| v&.to_datetime }
|
81
|
+
else
|
82
|
+
value&.to_datetime
|
83
|
+
end
|
84
|
+
else
|
85
|
+
value
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class Jason::ConsistencyChecker
|
2
|
+
attr_reader :subscription
|
3
|
+
attr_reader :inconsistent
|
4
|
+
|
5
|
+
def self.check_all(fix: false)
|
6
|
+
Jason::Subscription.all.each do |sub|
|
7
|
+
next if sub.consumer_count == 0
|
8
|
+
checker = Jason::ConsistencyChecker.new(sub)
|
9
|
+
result = checker.check
|
10
|
+
if checker.inconsistent?
|
11
|
+
pp sub.config
|
12
|
+
pp result
|
13
|
+
if fix
|
14
|
+
sub.reset!(hard: true)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.fix_all
|
21
|
+
check_all(fix: true)
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(subscription)
|
25
|
+
@subscription = subscription
|
26
|
+
@inconsistent = false
|
27
|
+
end
|
28
|
+
|
29
|
+
def inconsistent?
|
30
|
+
inconsistent
|
31
|
+
end
|
32
|
+
|
33
|
+
# Take a subscription, get the current cached payload, and compare it to the data retrieved from the database
|
34
|
+
def check
|
35
|
+
cached_payload = subscription.get
|
36
|
+
edge_set = subscription.load_ids_for_sub_models(subscription.model, nil)
|
37
|
+
|
38
|
+
result = cached_payload.map do |model_name, data|
|
39
|
+
cached_payload_instance_ids = data[:payload].map { |row| row['id'] }
|
40
|
+
|
41
|
+
model_idx = edge_set[:model_names].index(model_name)
|
42
|
+
if model_idx.present?
|
43
|
+
edge_set_instance_ids = edge_set[:instance_ids].map { |row| row[model_idx] }
|
44
|
+
else
|
45
|
+
next
|
46
|
+
end
|
47
|
+
|
48
|
+
missing = edge_set_instance_ids - cached_payload_instance_ids
|
49
|
+
intruding = cached_payload_instance_ids - edge_set_instance_ids
|
50
|
+
|
51
|
+
if missing.present? || intruding.present?
|
52
|
+
@inconsistent = true
|
53
|
+
end
|
54
|
+
|
55
|
+
[model_name, {
|
56
|
+
'missing' => missing,
|
57
|
+
'intruding' => intruding
|
58
|
+
}]
|
59
|
+
end.compact.to_h
|
60
|
+
end
|
61
|
+
end
|
data/lib/jason/graph_helper.rb
CHANGED
@@ -26,6 +26,10 @@ class Jason::GraphHelper
|
|
26
26
|
$redis_jason.srem("jason:subscriptions:#{id}:graph", edges)
|
27
27
|
end
|
28
28
|
|
29
|
+
def apply_add_node_at_root(node)
|
30
|
+
diff_edges_from_graph(add_edges: ["root/#{node}"])
|
31
|
+
end
|
32
|
+
|
29
33
|
def apply_remove_node(node)
|
30
34
|
edges = $redis_jason.smembers("jason:subscriptions:#{id}:graph")
|
31
35
|
edges = find_edges_with_node(edges, node)
|
@@ -33,7 +37,8 @@ class Jason::GraphHelper
|
|
33
37
|
end
|
34
38
|
|
35
39
|
# Add and remove edges, return graph before and after
|
36
|
-
|
40
|
+
# Enforce means make the graph contain only the add_edges
|
41
|
+
def apply_update(add: nil, remove: nil, enforce: false)
|
37
42
|
add_edges = []
|
38
43
|
remove_edges = []
|
39
44
|
|
@@ -48,11 +53,21 @@ class Jason::GraphHelper
|
|
48
53
|
remove_edges += build_edges(edge_set[:model_names], edge_set[:instance_ids], include_root: false)
|
49
54
|
end
|
50
55
|
end
|
51
|
-
|
56
|
+
|
57
|
+
diff_edges_from_graph(add_edges: add_edges, remove_edges: remove_edges, enforce: enforce)
|
52
58
|
end
|
53
59
|
|
54
|
-
def diff_edges_from_graph(add_edges: [], remove_edges: [])
|
55
|
-
|
60
|
+
def diff_edges_from_graph(add_edges: [], remove_edges: [], enforce: false)
|
61
|
+
if enforce
|
62
|
+
old_edges = $redis_jason.multi do |r|
|
63
|
+
r.smembers("jason:subscriptions:#{id}:graph")
|
64
|
+
r.del("jason:subscriptions:#{id}:graph")
|
65
|
+
r.sadd("jason:subscriptions:#{id}:graph", add_edges) if add_edges.present?
|
66
|
+
end[0]
|
67
|
+
new_edges = add_edges
|
68
|
+
else
|
69
|
+
old_edges, new_edges = Jason::LuaGenerator.new.update_set_with_diff("jason:subscriptions:#{id}:graph", add_edges.flatten, remove_edges.flatten)
|
70
|
+
end
|
56
71
|
|
57
72
|
old_graph = build_graph_from_edges(old_edges)
|
58
73
|
new_graph = build_graph_from_edges(new_edges)
|
data/lib/jason/publisher.rb
CHANGED
@@ -5,6 +5,7 @@ module Jason::Publisher
|
|
5
5
|
def self.cache_all
|
6
6
|
Rails.application.eager_load!
|
7
7
|
ActiveRecord::Base.descendants.each do |klass|
|
8
|
+
$redis_jason.del("jason:cache:#{klass.name.underscore}")
|
8
9
|
klass.cache_all if klass.respond_to?(:cache_all)
|
9
10
|
end
|
10
11
|
end
|
@@ -42,7 +43,9 @@ module Jason::Publisher
|
|
42
43
|
# - TODO: The value of an instance changes so that it enters/leaves a subscription
|
43
44
|
|
44
45
|
# TODO: Optimize this, by caching associations rather than checking each time instance is saved
|
45
|
-
jason_assocs = self.class.reflect_on_all_associations(:belongs_to)
|
46
|
+
jason_assocs = self.class.reflect_on_all_associations(:belongs_to)
|
47
|
+
.reject { |assoc| assoc.polymorphic? } # Can't get the class name of a polymorphic association, by
|
48
|
+
.select { |assoc| assoc.klass.respond_to?(:has_jason?) }
|
46
49
|
jason_assocs.each do |assoc|
|
47
50
|
if previous_changes[assoc.foreign_key].present?
|
48
51
|
Jason::Subscription.update_ids(
|
@@ -70,13 +73,38 @@ module Jason::Publisher
|
|
70
73
|
)
|
71
74
|
end
|
72
75
|
|
73
|
-
# - An instance is created where it belongs_to an _all_ subscription
|
74
|
-
if previous_changes['id'].present?
|
75
|
-
Jason::Subscription.add_id(self.class.name.underscore, id)
|
76
|
-
end
|
77
|
-
|
78
76
|
if persisted?
|
77
|
+
applied_sub_ids = []
|
78
|
+
|
79
|
+
jason_conditions.each do |row|
|
80
|
+
matches = row['conditions'].map do |key, rules|
|
81
|
+
Jason::ConditionsMatcher.new(self.class).test_match(key, rules, previous_changes)
|
82
|
+
end
|
83
|
+
next if matches.all? { |m| m.nil? } # None of the keys were in previous changes - therefore this condition does not apply
|
84
|
+
in_sub = matches.all? { |m| m }
|
85
|
+
|
86
|
+
if in_sub
|
87
|
+
row['subscription_ids'].each do |sub_id|
|
88
|
+
Jason::Subscription.find_by_id(sub_id).add_id(self.class.name.underscore, self.id)
|
89
|
+
applied_sub_ids.push(sub_id)
|
90
|
+
end
|
91
|
+
else
|
92
|
+
row['subscription_ids'].each do |sub_id|
|
93
|
+
jason_subscriptions.each do |already_sub_id|
|
94
|
+
# If this sub ID already has this instance, remove it
|
95
|
+
if already_sub_id == sub_id
|
96
|
+
sub = Jason::Subscription.find_by_id(already_sub_id)
|
97
|
+
sub.remove_id(self.class.name.underscore, self.id)
|
98
|
+
applied_sub_ids.push(already_sub_id)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
79
105
|
jason_subscriptions.each do |sub_id|
|
106
|
+
next if applied_sub_ids.include?(sub_id)
|
107
|
+
|
80
108
|
Jason::Subscription.new(id: sub_id).update(self.class.name.underscore, id, payload, gidx)
|
81
109
|
end
|
82
110
|
end
|
@@ -91,6 +119,10 @@ module Jason::Publisher
|
|
91
119
|
Jason::Subscription.for_instance(self.class.name.underscore, id)
|
92
120
|
end
|
93
121
|
|
122
|
+
def jason_conditions
|
123
|
+
Jason::Subscription.conditions_for_model(self.class.name.underscore)
|
124
|
+
end
|
125
|
+
|
94
126
|
def jason_cached_value
|
95
127
|
JSON.parse($redis_jason.hget("jason:cache:#{self.class.name.underscore}", id) || '{}')
|
96
128
|
end
|
@@ -115,7 +147,8 @@ module Jason::Publisher
|
|
115
147
|
self.after_initialize -> {
|
116
148
|
@api_model = Jason::ApiModel.new(self.class.name.underscore)
|
117
149
|
}
|
118
|
-
self.after_commit :
|
150
|
+
self.after_commit :force_publish_json, on: [:create, :destroy]
|
151
|
+
self.after_commit :publish_json_if_changed, on: [:update]
|
119
152
|
end
|
120
153
|
|
121
154
|
def find_or_create_by_id(params)
|