jason-rails 0.7.1 → 0.8.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 +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
|