admin管理员组文章数量:1391969
I am writing an electron app and I keep all my app data inside a single MST tree. Now I noticed that every now and then you run into a situation where data bees inconsistent (missing reference object etc). While this can happen with any type of database, I see a particular problem with MST:
Since we have a single tree which is deserialised on start of the app and then used as a single snapshot, a single inconsistency will cause the whole application to fail. Not a single piece of data will be available to my application.
Any hints on how to deal with that?
More information
Currently I create a snapshot everytime the tree changes (onSnapshot) and save it in localStorage. So a error-usecase would be: create mst object -> create reference in some other part of the tree -> delete mst object -> onSnapshot gets triggered -> corrupt tree gets persisted. Reloading the application won't help, cause tree is persisted in corrupt state.
I am writing an electron app and I keep all my app data inside a single MST tree. Now I noticed that every now and then you run into a situation where data bees inconsistent (missing reference object etc). While this can happen with any type of database, I see a particular problem with MST:
Since we have a single tree which is deserialised on start of the app and then used as a single snapshot, a single inconsistency will cause the whole application to fail. Not a single piece of data will be available to my application.
Any hints on how to deal with that?
More information
Currently I create a snapshot everytime the tree changes (onSnapshot) and save it in localStorage. So a error-usecase would be: create mst object -> create reference in some other part of the tree -> delete mst object -> onSnapshot gets triggered -> corrupt tree gets persisted. Reloading the application won't help, cause tree is persisted in corrupt state.
Share Improve this question edited Sep 4, 2019 at 8:47 stoefln asked Sep 3, 2019 at 8:05 stoeflnstoefln 14.6k18 gold badges86 silver badges149 bronze badges 3- That actually sounds like a serious issue. If you can create reproducible codesandbox, you should perhaps open a ticket on github. – jayarjo Commented Sep 4, 2019 at 7:53
- How did this go, did you figure out what was causing inconsistency? Or how do you deal with it? Any followup might be helpful for us here as well. – jayarjo Commented Oct 8, 2019 at 6:11
- I haven't implemented it but I am planning to validate my store every 10 seconds and save it ONLY when the validation succeeds. – stoefln Commented Oct 14, 2019 at 19:36
2 Answers
Reset to default 5 +100In order to avoid not consistent ining data, I'm adding defaults in my models. For example
const collectionModel = types.model({
type: types.optional(types.literal('collections'), 'collections'),
preview: types.optional(
types.model({
products: types.array(SelectableProduct)
}),
{}
),
data: types.optional(types.model({
items: 24,
perRow: 4,
global: types.optional(EvergreenQuery, {}),
curated: types.array(EvergreenItemSettings)
}), {})
})
This will allow me to create an instance of collectionModel
from an empty object
collection1 = collectionModel.create({})
When you are using references make sure to use safeReference
From the docs
* `types.safeReference` - A safe reference is like a standard reference, except that it accepts the undefined value by default
* and automatically sets itself to undefined (when the parent is a model) / removes itself from arrays and maps
* when the reference it is pointing to gets detached/destroyed.
*
* Strictly speaking it is a `types.maybe(types.reference(X))` with a customized `onInvalidate` option.
So if you are removing a node that is referenced somewhere else in the store, then that reference will get set to undefined. From my experience, broken references are especially difficult to debug.
I like that mobx-state-tree forces me to have a defined structure. This makes me think of the structure before writing the logic which later simplifies writing the logic.
A Hacky solution
A hack that you could do is before saving the snapshot instantiate a new model. If it succeeds then save the snapshot, if not skip it.
const MyModel = types.model({})
onSnapshot(myModelInstance, s => {
try {
const testModel = MyModel.create(s)
if (localStorage) {
// here you can save the snapshot because you know for sure it won't break
localStorage.setItem('snap', JSON.stringify(s))
}
} catch(e) {
// log or something
// OR
console.log(
'snapshot failed because of',
difference(s, JSON.parse(localStorage.getItem('snap'))
)
}
})
// this methos does a deep difference between two objects
export const difference = <T>(orObject: object, orBase: object): T => {
function changes(object: any, base: any): any {
return _.transform(object, function(
result: any,
value: any,
key: any
): any {
if (!_.isEqual(value, base[key])) {
result[key] =
_.isObject(value) && _.isObject(base[key])
? changes(value, base[key])
: value;
}
});
}
return changes(orObject, orBase);
};
The diff method is very helpfull because it will make it easier to figure out what is the cause of the crash. In this way, the localStorage will have only valid snapshots and any invalid snapshot will log the cause of the issues.
Where is the data for the deserialisation ing from ? I'm not that familiar with electron but I imagine you store it locally (by snapshotting the mst tree) in between app sessions.
My first hunch would be to look what happens when you serialise it? Maybe it'd be a good idea to validate the snapshot before saving it (I imagine on app close?) ?
Is the inconsistency 'consistent'? What I mean is - is it the same part of the tree that causes it ? Maybe split the tree - serialise -> deserialise multiple snapshots of different parts instead of 1 big thing.
While I do use mst, I don't use snapshotting, not at whole tree lvl at least, check if the tree gets frozen when the snapshot is created .. maybe, unlikely I think, changes are still done on the tree while the snapshot is being written.
本文标签: javascriptHow to deal with inconsistent mobxstatetree snapshotsStack Overflow
版权声明:本文标题:javascript - How to deal with inconsistent mobx-state-tree snapshots? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744756308a2623482.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论