jason-rails 0.7.1 → 0.8.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/CHANGELOG.md +13 -0
- data/Gemfile.lock +4 -3
- data/README.md +15 -1
- data/client/lib/JasonProvider.d.ts +3 -1
- data/client/lib/JasonProvider.js +2 -2
- data/client/lib/createTransportAdapter.d.ts +1 -1
- data/client/lib/createTransportAdapter.js +2 -2
- data/client/lib/index.d.ts +8 -1
- data/client/lib/index.js +3 -1
- data/client/lib/transportAdapters/actionCableAdapter.d.ts +1 -1
- data/client/lib/transportAdapters/actionCableAdapter.js +3 -2
- data/client/lib/useJason.d.ts +3 -1
- data/client/lib/useJason.js +4 -4
- data/client/package.json +1 -1
- data/client/src/JasonProvider.tsx +2 -2
- data/client/src/createTransportAdapter.ts +2 -2
- data/client/src/index.ts +2 -0
- data/client/src/transportAdapters/actionCableAdapter.ts +4 -2
- data/client/src/useJason.ts +10 -4
- data/lib/jason/consistency_checker.rb +4 -0
- data/lib/jason/lua_generator.rb +20 -6
- data/lib/jason/publisher.rb +7 -3
- data/lib/jason/subscription.rb +11 -8
- data/lib/jason/version.rb +1 -1
- data/lib/jason.rb +5 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 592a7eab8028ae28815abbf0d401d98b2ceabc0009f30713f68795da21adb165
|
4
|
+
data.tar.gz: 315f5088e258dcab9755dc92f4de03f3f2f016cf6698d3619f022c1e7d601e9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a33fdc1d57462a97b7dd571222ff314cc77338e5172fcfc662f3e1fd5f008deed299abcd870900d0b50805944af822b462f6adee46953895499ce49f69df6680
|
7
|
+
data.tar.gz: 8ec1a59761856754f09bb7b6431d3d45d319daf9d4c7f030b8c7c2301c28ab2d0393952c4d7339a4d6310da2689c3cba8c71048deed931e0d3c4b0cf5c2fc2f1
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
## v0.8.0
|
2
|
+
- Cold cache handling:
|
3
|
+
- Expiry is now set on all cached models of one week
|
4
|
+
- Code now handles case where cached model is missing and repopulates the cache
|
5
|
+
|
6
|
+
## v0.7.5
|
7
|
+
- Fixed JS errors when payloads arrive on websockets after the subscription has been unmounted
|
8
|
+
- Fixed errors during initialization due to calling `cache_all` on a Rails model before it had fully initialized.
|
9
|
+
|
10
|
+
## v0.7.3
|
11
|
+
- Added: Add JasonContext to exports, for use in scenarios where you need to forward the context into some other React reconciler (e.g. `react-three-fiber`)
|
12
|
+
- Fixed: Unneeded `reload` in Publisher resulting in extra database calls
|
13
|
+
|
1
14
|
## v0.7.1
|
2
15
|
- Added: Authorization for REST endpoints. Previously these just inherited logic from ApplicationController. Pass a `update_authorization_service` option to the Jason initializer to use this.
|
3
16
|
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
jason-rails (0.7.
|
4
|
+
jason-rails (0.7.5)
|
5
5
|
connection_pool (>= 2.2.3)
|
6
6
|
jsondiff
|
7
7
|
rails (>= 5)
|
@@ -89,9 +89,10 @@ GEM
|
|
89
89
|
marcel (0.3.3)
|
90
90
|
mimemagic (~> 0.3.2)
|
91
91
|
method_source (1.0.0)
|
92
|
-
mimemagic (0.3.
|
92
|
+
mimemagic (0.3.10)
|
93
93
|
nokogiri (~> 1)
|
94
|
-
|
94
|
+
rake
|
95
|
+
mini_mime (1.1.0)
|
95
96
|
mini_portile2 (2.5.0)
|
96
97
|
minitest (5.14.3)
|
97
98
|
nio4r (2.5.7)
|
data/README.md
CHANGED
@@ -21,7 +21,7 @@ An alternative way of thinking about Jason is "what if we applied the Flux/Redux
|
|
21
21
|
Add the gem and the NPM package
|
22
22
|
|
23
23
|
```ruby
|
24
|
-
gem 'jason-rails'
|
24
|
+
gem 'jason-rails', require: 'jason'
|
25
25
|
```
|
26
26
|
|
27
27
|
```bash
|
@@ -52,6 +52,11 @@ Jason.setup do |config|
|
|
52
52
|
end
|
53
53
|
```
|
54
54
|
|
55
|
+
Mount the Jason engine in `routes.rb`
|
56
|
+
```ruby
|
57
|
+
mount Jason::Engine => "/jason"
|
58
|
+
```
|
59
|
+
|
55
60
|
### In your frontend code
|
56
61
|
|
57
62
|
First you need to wrap your root component in a `JasonProvider`.
|
@@ -173,6 +178,15 @@ Development is primarily driven by the needs of projects we're using Jason in. I
|
|
173
178
|
- Assess using RedisGraph for the graph diffing functionality, to see if this would provide a performance boost
|
174
179
|
- Improve the Typescript definitions (ie remove the abundant `any` typing currently used)
|
175
180
|
|
181
|
+
## Publishing a new version
|
182
|
+
- Update `version.rb`
|
183
|
+
- Update CHANGELOG
|
184
|
+
- `gem build`
|
185
|
+
- `gem push`
|
186
|
+
- `npm version [major/minor/patch]`
|
187
|
+
- `npm publish`
|
188
|
+
- Push new version to Github
|
189
|
+
|
176
190
|
## License
|
177
191
|
|
178
192
|
The gem, npm package and source code in the git repository are available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -1,8 +1,10 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
declare const JasonProvider: ({ reducers, middleware, extraActions, children }: {
|
2
|
+
declare const JasonProvider: ({ reducers, middleware, enhancers, extraActions, transportOptions, children }: {
|
3
3
|
reducers?: any;
|
4
4
|
middleware?: any;
|
5
|
+
enhancers?: any;
|
5
6
|
extraActions?: any;
|
7
|
+
transportOptions?: any;
|
6
8
|
children?: React.FC<{}> | undefined;
|
7
9
|
}) => JSX.Element;
|
8
10
|
export default JasonProvider;
|
data/client/lib/JasonProvider.js
CHANGED
@@ -7,8 +7,8 @@ const react_1 = __importDefault(require("react"));
|
|
7
7
|
const useJason_1 = __importDefault(require("./useJason"));
|
8
8
|
const react_redux_1 = require("react-redux");
|
9
9
|
const JasonContext_1 = __importDefault(require("./JasonContext"));
|
10
|
-
const JasonProvider = ({ reducers, middleware, extraActions, children }) => {
|
11
|
-
const [store, value] = useJason_1.default({ reducers, middleware, extraActions });
|
10
|
+
const JasonProvider = ({ reducers, middleware, enhancers, extraActions, transportOptions = {}, children }) => {
|
11
|
+
const [store, value] = useJason_1.default({ reducers, middleware, enhancers, extraActions, transportOptions });
|
12
12
|
if (!(store && value))
|
13
13
|
return react_1.default.createElement("div", null); // Wait for async fetch of schema to complete
|
14
14
|
return react_1.default.createElement(react_redux_1.Provider, { store: store },
|
@@ -1,4 +1,4 @@
|
|
1
|
-
export default function createTransportAdapter(jasonConfig: any, handlePayload: any, dispatch: any, onConnect: any): {
|
1
|
+
export default function createTransportAdapter(jasonConfig: any, handlePayload: any, dispatch: any, onConnect: any, transportOptions: any): {
|
2
2
|
getPayload: (config: any, options: any) => void;
|
3
3
|
createSubscription: (config: any) => void;
|
4
4
|
removeSubscription: (config: any) => void;
|
@@ -5,10 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
6
|
const actionCableAdapter_1 = __importDefault(require("./transportAdapters/actionCableAdapter"));
|
7
7
|
const pusherAdapter_1 = __importDefault(require("./transportAdapters/pusherAdapter"));
|
8
|
-
function createTransportAdapter(jasonConfig, handlePayload, dispatch, onConnect) {
|
8
|
+
function createTransportAdapter(jasonConfig, handlePayload, dispatch, onConnect, transportOptions) {
|
9
9
|
const { transportService } = jasonConfig;
|
10
10
|
if (transportService === 'action_cable') {
|
11
|
-
return actionCableAdapter_1.default(jasonConfig, handlePayload, dispatch, onConnect);
|
11
|
+
return actionCableAdapter_1.default(jasonConfig, handlePayload, dispatch, onConnect, transportOptions);
|
12
12
|
}
|
13
13
|
else if (transportService === 'pusher') {
|
14
14
|
return pusherAdapter_1.default(jasonConfig, handlePayload, dispatch);
|
data/client/lib/index.d.ts
CHANGED
@@ -2,10 +2,17 @@
|
|
2
2
|
import _useAct from './useAct';
|
3
3
|
import _useSub from './useSub';
|
4
4
|
import _useEager from './useEager';
|
5
|
-
export declare const
|
5
|
+
export declare const JasonContext: import("react").Context<{
|
6
|
+
actions: any;
|
7
|
+
subscribe: null;
|
8
|
+
eager: (entity: any, id: any, relations: any) => void;
|
9
|
+
}>;
|
10
|
+
export declare const JasonProvider: ({ reducers, middleware, enhancers, extraActions, transportOptions, children }: {
|
6
11
|
reducers?: any;
|
7
12
|
middleware?: any;
|
13
|
+
enhancers?: any;
|
8
14
|
extraActions?: any;
|
15
|
+
transportOptions?: any;
|
9
16
|
children?: import("react").FC<{}> | undefined;
|
10
17
|
}) => JSX.Element;
|
11
18
|
export declare const useAct: typeof _useAct;
|
data/client/lib/index.js
CHANGED
@@ -3,11 +3,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.useEager = exports.useSub = exports.useAct = exports.JasonProvider = void 0;
|
6
|
+
exports.useEager = exports.useSub = exports.useAct = exports.JasonProvider = exports.JasonContext = void 0;
|
7
|
+
const JasonContext_1 = __importDefault(require("./JasonContext"));
|
7
8
|
const JasonProvider_1 = __importDefault(require("./JasonProvider"));
|
8
9
|
const useAct_1 = __importDefault(require("./useAct"));
|
9
10
|
const useSub_1 = __importDefault(require("./useSub"));
|
10
11
|
const useEager_1 = __importDefault(require("./useEager"));
|
12
|
+
exports.JasonContext = JasonContext_1.default;
|
11
13
|
exports.JasonProvider = JasonProvider_1.default;
|
12
14
|
exports.useAct = useAct_1.default;
|
13
15
|
exports.useSub = useSub_1.default;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
export default function actionCableAdapter(jasonConfig: any, handlePayload: any, dispatch: any, onConnected: any): {
|
1
|
+
export default function actionCableAdapter(jasonConfig: any, handlePayload: any, dispatch: any, onConnected: any, transportOptions: any): {
|
2
2
|
getPayload: (config: any, options: any) => void;
|
3
3
|
createSubscription: (config: any) => void;
|
4
4
|
removeSubscription: (config: any) => void;
|
@@ -7,9 +7,10 @@ const actioncable_1 = require("@rails/actioncable");
|
|
7
7
|
const restClient_1 = __importDefault(require("../restClient"));
|
8
8
|
const uuid_1 = require("uuid");
|
9
9
|
const lodash_1 = __importDefault(require("lodash"));
|
10
|
-
function actionCableAdapter(jasonConfig, handlePayload, dispatch, onConnected) {
|
10
|
+
function actionCableAdapter(jasonConfig, handlePayload, dispatch, onConnected, transportOptions) {
|
11
11
|
const consumerId = uuid_1.v4();
|
12
|
-
const
|
12
|
+
const { cableUrl } = transportOptions;
|
13
|
+
const consumer = cableUrl ? actioncable_1.createConsumer(cableUrl) : actioncable_1.createConsumer();
|
13
14
|
const subscription = (consumer.subscriptions.create({
|
14
15
|
channel: 'Jason::Channel'
|
15
16
|
}, {
|
data/client/lib/useJason.d.ts
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
export default function useJason({ reducers, middleware, extraActions }: {
|
1
|
+
export default function useJason({ reducers, middleware, enhancers, transportOptions, extraActions }: {
|
2
2
|
reducers?: any;
|
3
3
|
middleware?: any[];
|
4
|
+
enhancers?: any[];
|
4
5
|
extraActions?: any;
|
6
|
+
transportOptions?: any;
|
5
7
|
}): any[];
|
data/client/lib/useJason.js
CHANGED
@@ -16,7 +16,7 @@ const humps_1 = require("humps");
|
|
16
16
|
const blueimp_md5_1 = __importDefault(require("blueimp-md5"));
|
17
17
|
const lodash_1 = __importDefault(require("lodash"));
|
18
18
|
const react_1 = require("react");
|
19
|
-
function useJason({ reducers, middleware = [], extraActions }) {
|
19
|
+
function useJason({ reducers, middleware = [], enhancers = [], transportOptions = {}, extraActions }) {
|
20
20
|
const [store, setStore] = react_1.useState(null);
|
21
21
|
const [value, setValue] = react_1.useState(null);
|
22
22
|
react_1.useEffect(() => {
|
@@ -28,7 +28,7 @@ function useJason({ reducers, middleware = [], extraActions }) {
|
|
28
28
|
const serverActionQueue = createServerActionQueue_1.default();
|
29
29
|
const allReducers = Object.assign(Object.assign({}, reducers), createJasonReducers_1.default(schema));
|
30
30
|
console.debug({ allReducers });
|
31
|
-
const store = toolkit_1.configureStore({ reducer: allReducers, middleware: [...middleware, pruneIdsMiddleware_1.default(schema)] });
|
31
|
+
const store = toolkit_1.configureStore({ reducer: allReducers, middleware: [...middleware, pruneIdsMiddleware_1.default(schema)], enhancers });
|
32
32
|
const dispatch = store.dispatch;
|
33
33
|
const optDis = createOptDis_1.default(schema, dispatch, restClient_1.default, serverActionQueue);
|
34
34
|
const actions = createActions_1.default(schema, store, restClient_1.default, optDis, extraActions);
|
@@ -37,7 +37,7 @@ function useJason({ reducers, middleware = [], extraActions }) {
|
|
37
37
|
let subOptions = {};
|
38
38
|
function handlePayload(payload) {
|
39
39
|
const { md5Hash } = payload;
|
40
|
-
const { handlePayload } = payloadHandlers[md5Hash];
|
40
|
+
const { handlePayload } = payloadHandlers[md5Hash] || {};
|
41
41
|
if (handlePayload) {
|
42
42
|
handlePayload(payload);
|
43
43
|
}
|
@@ -45,7 +45,7 @@ function useJason({ reducers, middleware = [], extraActions }) {
|
|
45
45
|
console.warn("Payload arrived with no handler", payload, payloadHandlers);
|
46
46
|
}
|
47
47
|
}
|
48
|
-
const transportAdapter = createTransportAdapter_1.default(jasonConfig, handlePayload, dispatch, () => lodash_1.default.keys(configs).forEach(md5Hash => createSubscription(configs[md5Hash], subOptions[md5Hash])));
|
48
|
+
const transportAdapter = createTransportAdapter_1.default(jasonConfig, handlePayload, dispatch, () => lodash_1.default.keys(configs).forEach(md5Hash => createSubscription(configs[md5Hash], subOptions[md5Hash])), transportOptions);
|
49
49
|
function createSubscription(config, options = {}) {
|
50
50
|
// We need the hash to be consistent in Ruby / Javascript
|
51
51
|
const hashableConfig = lodash_1.default(Object.assign({ conditions: {}, includes: {} }, config)).toPairs().sortBy(0).fromPairs().value();
|
data/client/package.json
CHANGED
@@ -3,8 +3,8 @@ import useJason from './useJason'
|
|
3
3
|
import { Provider } from 'react-redux'
|
4
4
|
import JasonContext from './JasonContext'
|
5
5
|
|
6
|
-
const JasonProvider = ({ reducers, middleware, extraActions, children }: { reducers?: any, middleware?: any, extraActions?: any, children?: React.FC }) => {
|
7
|
-
const [store, value] = useJason({ reducers, middleware, extraActions })
|
6
|
+
const JasonProvider = ({ reducers, middleware, enhancers, extraActions, transportOptions = {}, children }: { reducers?: any, middleware?: any, enhancers?: any, extraActions?: any, transportOptions?: any, children?: React.FC }) => {
|
7
|
+
const [store, value] = useJason({ reducers, middleware, enhancers, extraActions, transportOptions })
|
8
8
|
|
9
9
|
if(!(store && value)) return <div /> // Wait for async fetch of schema to complete
|
10
10
|
|
@@ -1,10 +1,10 @@
|
|
1
1
|
import actionCableAdapter from './transportAdapters/actionCableAdapter'
|
2
2
|
import pusherAdapter from './transportAdapters/pusherAdapter'
|
3
3
|
|
4
|
-
export default function createTransportAdapter(jasonConfig, handlePayload, dispatch, onConnect) {
|
4
|
+
export default function createTransportAdapter(jasonConfig, handlePayload, dispatch, onConnect, transportOptions) {
|
5
5
|
const { transportService } = jasonConfig
|
6
6
|
if (transportService === 'action_cable') {
|
7
|
-
return actionCableAdapter(jasonConfig, handlePayload, dispatch, onConnect)
|
7
|
+
return actionCableAdapter(jasonConfig, handlePayload, dispatch, onConnect, transportOptions)
|
8
8
|
} else if (transportService === 'pusher') {
|
9
9
|
return pusherAdapter(jasonConfig, handlePayload, dispatch)
|
10
10
|
} else {
|
data/client/src/index.ts
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
import _JasonContext from './JasonContext'
|
1
2
|
import _JasonProvider from './JasonProvider'
|
2
3
|
import _useAct from './useAct'
|
3
4
|
import _useSub from './useSub'
|
4
5
|
import _useEager from './useEager'
|
5
6
|
|
7
|
+
export const JasonContext = _JasonContext
|
6
8
|
export const JasonProvider = _JasonProvider
|
7
9
|
export const useAct = _useAct
|
8
10
|
export const useSub = _useSub
|
@@ -3,10 +3,12 @@ import restClient from '../restClient'
|
|
3
3
|
import { v4 as uuidv4 } from 'uuid'
|
4
4
|
import _ from 'lodash'
|
5
5
|
|
6
|
-
export default function actionCableAdapter(jasonConfig, handlePayload, dispatch, onConnected) {
|
6
|
+
export default function actionCableAdapter(jasonConfig, handlePayload, dispatch, onConnected, transportOptions) {
|
7
7
|
const consumerId = uuidv4()
|
8
8
|
|
9
|
-
const
|
9
|
+
const { cableUrl } = transportOptions
|
10
|
+
const consumer = cableUrl ? createConsumer(cableUrl) : createConsumer()
|
11
|
+
|
10
12
|
const subscription = (consumer.subscriptions.create({
|
11
13
|
channel: 'Jason::Channel'
|
12
14
|
}, {
|
data/client/src/useJason.ts
CHANGED
@@ -14,7 +14,7 @@ import md5 from 'blueimp-md5'
|
|
14
14
|
import _ from 'lodash'
|
15
15
|
import React, { useState, useEffect } from 'react'
|
16
16
|
|
17
|
-
export default function useJason({ reducers, middleware = [], extraActions }: { reducers?: any, middleware?: any[], extraActions?: any }) {
|
17
|
+
export default function useJason({ reducers, middleware = [], enhancers = [], transportOptions = {}, extraActions }: { reducers?: any, middleware?: any[], enhancers?: any[], extraActions?: any, transportOptions?: any }) {
|
18
18
|
const [store, setStore] = useState(null as any)
|
19
19
|
const [value, setValue] = useState(null as any)
|
20
20
|
|
@@ -35,7 +35,7 @@ export default function useJason({ reducers, middleware = [], extraActions }: {
|
|
35
35
|
|
36
36
|
console.debug({ allReducers })
|
37
37
|
|
38
|
-
const store = configureStore({ reducer: allReducers, middleware: [...middleware, pruneIdsMiddleware(schema)] })
|
38
|
+
const store = configureStore({ reducer: allReducers, middleware: [...middleware, pruneIdsMiddleware(schema)], enhancers })
|
39
39
|
const dispatch = store.dispatch
|
40
40
|
|
41
41
|
const optDis = createOptDis(schema, dispatch, restClient, serverActionQueue)
|
@@ -48,7 +48,7 @@ export default function useJason({ reducers, middleware = [], extraActions }: {
|
|
48
48
|
function handlePayload(payload) {
|
49
49
|
const { md5Hash } = payload
|
50
50
|
|
51
|
-
const { handlePayload } = payloadHandlers[md5Hash]
|
51
|
+
const { handlePayload } = payloadHandlers[md5Hash] || {}
|
52
52
|
if (handlePayload) {
|
53
53
|
handlePayload(payload)
|
54
54
|
} else {
|
@@ -56,7 +56,13 @@ export default function useJason({ reducers, middleware = [], extraActions }: {
|
|
56
56
|
}
|
57
57
|
}
|
58
58
|
|
59
|
-
const transportAdapter = createTransportAdapater(
|
59
|
+
const transportAdapter = createTransportAdapater(
|
60
|
+
jasonConfig,
|
61
|
+
handlePayload,
|
62
|
+
dispatch,
|
63
|
+
() => _.keys(configs).forEach(md5Hash => createSubscription(configs[md5Hash], subOptions[md5Hash])),
|
64
|
+
transportOptions
|
65
|
+
)
|
60
66
|
|
61
67
|
function createSubscription(config, options = {}) {
|
62
68
|
// We need the hash to be consistent in Ruby / Javascript
|
data/lib/jason/lua_generator.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
class Jason::LuaGenerator
|
2
2
|
## TODO load these scripts and evalsha
|
3
3
|
def cache_json(model_name, id, payload)
|
4
|
+
expiry = 7*24*60*60 + rand(6*60*60)
|
5
|
+
|
6
|
+
# ensure the content expires first
|
4
7
|
cmd = <<~LUA
|
5
8
|
local gidx = redis.call('INCR', 'jason:gidx')
|
6
|
-
redis.call( '
|
7
|
-
redis.call( '
|
9
|
+
redis.call( 'setex', 'jason:cache:' .. ARGV[1] .. ':' .. ARGV[2] .. ':gidx', #{expiry}, gidx )
|
10
|
+
redis.call( 'setex', 'jason:cache:' .. ARGV[1] .. ':' .. ARGV[2], #{expiry - 60}, ARGV[3] )
|
8
11
|
return gidx
|
9
12
|
LUA
|
10
13
|
|
@@ -15,15 +18,26 @@ class Jason::LuaGenerator
|
|
15
18
|
# If value has changed, return old value and new idx. Otherwise do nothing.
|
16
19
|
cmd = <<~LUA
|
17
20
|
local t = {}
|
18
|
-
local
|
21
|
+
local insts = {}
|
22
|
+
local miss_ids = {}
|
19
23
|
local ids = redis.call('smembers', 'jason:subscriptions:' .. ARGV[2] .. ':ids:' .. ARGV[1])
|
20
24
|
|
21
25
|
for k,id in pairs(ids) do
|
22
|
-
|
26
|
+
local result = redis.call( 'get', 'jason:cache:' .. ARGV[1] .. ':' .. id)
|
27
|
+
if (result == false) then
|
28
|
+
miss_ids[#miss_ids+1] = id
|
29
|
+
else
|
30
|
+
insts[#insts+1] = result
|
31
|
+
end
|
23
32
|
end
|
24
33
|
|
25
|
-
|
26
|
-
|
34
|
+
if next(miss_ids) == nil then
|
35
|
+
t[#t+1] = insts
|
36
|
+
t[#t+1] = redis.call( 'get', 'jason:subscription:' .. ARGV[2] .. ':' .. ARGV[1] .. ':idx' )
|
37
|
+
else
|
38
|
+
t[#t+1] = miss_ids
|
39
|
+
t[#t+1] = 'missing'
|
40
|
+
end
|
27
41
|
|
28
42
|
return t
|
29
43
|
LUA
|
data/lib/jason/publisher.rb
CHANGED
@@ -16,7 +16,7 @@ module Jason::Publisher
|
|
16
16
|
|
17
17
|
# Exists
|
18
18
|
if self.persisted? && (scope.blank? || self.class.unscoped.send(scope).exists?(self.id))
|
19
|
-
payload = self.
|
19
|
+
payload = self.as_json(as_json_config)
|
20
20
|
gidx = Jason::LuaGenerator.new.cache_json(self.class.name.underscore, self.id, payload)
|
21
21
|
return [payload, gidx]
|
22
22
|
# Has been destroyed
|
@@ -124,12 +124,16 @@ module Jason::Publisher
|
|
124
124
|
end
|
125
125
|
|
126
126
|
def jason_cached_value
|
127
|
-
JSON.parse($redis_jason.
|
127
|
+
JSON.parse($redis_jason.get("jason:cache:#{self.class.name.underscore}:#{id}") || '{}')
|
128
128
|
end
|
129
129
|
|
130
130
|
class_methods do
|
131
131
|
def cache_all
|
132
|
-
all.
|
132
|
+
all.find_each(&:cache_json)
|
133
|
+
end
|
134
|
+
|
135
|
+
def cache_for(ids)
|
136
|
+
where(id: ids).find_each(&:cache_json)
|
133
137
|
end
|
134
138
|
|
135
139
|
def has_jason?
|
data/lib/jason/subscription.rb
CHANGED
@@ -399,16 +399,17 @@ class Jason::Subscription
|
|
399
399
|
end
|
400
400
|
|
401
401
|
def get_for_model(model_name)
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
end
|
407
|
-
instance_jsons = instance_jsons_hash.values
|
408
|
-
else
|
402
|
+
instance_jsons, idx = Jason::LuaGenerator.new.get_payload(model_name, id)
|
403
|
+
if idx == 'missing'
|
404
|
+
# warm cache and then retry
|
405
|
+
model_klass(model_name).cache_for(instance_jsons)
|
409
406
|
instance_jsons, idx = Jason::LuaGenerator.new.get_payload(model_name, id)
|
410
407
|
end
|
411
408
|
|
409
|
+
if instance_jsons.any? { |json| json.blank? }
|
410
|
+
raise Jason::MissingCacheError
|
411
|
+
end
|
412
|
+
|
412
413
|
payload = instance_jsons.map do |instance_json|
|
413
414
|
instance_json ? JSON.parse(instance_json) : {}
|
414
415
|
end
|
@@ -437,7 +438,7 @@ class Jason::Subscription
|
|
437
438
|
|
438
439
|
def add(model_name, instance_id)
|
439
440
|
idx = $redis_jason.incr("jason:subscription:#{id}:#{model_name}:idx")
|
440
|
-
payload = JSON.parse($redis_jason.
|
441
|
+
payload = JSON.parse($redis_jason.get("jason:cache:#{model_name}:#{instance_id}") || '{}')
|
441
442
|
|
442
443
|
payload = {
|
443
444
|
id: instance_id,
|
@@ -479,3 +480,5 @@ class Jason::Subscription
|
|
479
480
|
broadcaster.broadcast(payload)
|
480
481
|
end
|
481
482
|
end
|
483
|
+
|
484
|
+
class Jason::MissingCacheError < StandardError; end
|
data/lib/jason/version.rb
CHANGED
data/lib/jason.rb
CHANGED
@@ -51,7 +51,11 @@ module Jason
|
|
51
51
|
puts "Old config was #{previous_schema[model]}"
|
52
52
|
puts "New config is #{config}"
|
53
53
|
puts "Rebuilding cache for #{model}"
|
54
|
-
|
54
|
+
|
55
|
+
# This is necessary to ensure all Rails methods have been added to model before we attempt to cache.
|
56
|
+
Rails.configuration.after_initialize do
|
57
|
+
model.classify.constantize.cache_all
|
58
|
+
end
|
55
59
|
puts "Done"
|
56
60
|
end
|
57
61
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jason-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Rees
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|