-
Notifications
You must be signed in to change notification settings - Fork 76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot findAll -> destroyRecord #237
Comments
Don't have time to look at your problem now. Take a look at this working code: https://github.com/broerse/ember-cli-blog/blob/master/app/routes/posts.js#L37 Will try to find time 😄 |
In case it helps, you can reproduce the problem in the app by running this in the console: var store = Myapp.__container__.lookup('service:store');
store.createRecord('post', {}).save()
.then(() => store.findAll('post')
.then(p => p.forEach(post => post.destroyRecord())))
Note, however, that if the var store = Myapp.__container__.lookup('service:store');
store.createRecord('post', {}).save()
.then(() => store.findAll('post')
.then(p => p.forEach(Ember.run.next(post => post.destroyRecord())))) // works It seems that the application avoids this problem (and perhaps this is also related to what was happening in #188) by never calling I found that by adding a simple acceptance test for this app in my fork I could intermittently reproduce the error when running with However, the only 100% reliable way to reproduce the problem that I have found so far is to use Also, it may be worth noting that I hope this information is helpful for fixing the problem. I have spent too much time already diving into this :/ |
This is not an ember-pouch issue. For lack of better vocabulary, this should be considered expected unexpected behaviour of Ember Data working within the confines of the ember scheduler and a quasi-async environment. It is completely possible that the record actually has been created but the store is in some intermediate state as it's waiting for a callback to resolve. You can use the
Yes, likely, and a good indicator that there might be more to investigate with how the ember scheduler assigns priority and/or determines batching order, but I think this has nothing to do with ember-pouch. |
I confess that I really do not understand enough about the inner workings of |
@jacobq I am not sure but I think this should be fixed already. What is your ember-data version? Edit: I see you user ember-data 3.5.0 already. That should work. Will take a look. |
I've made a ember-data issue. For now it might be good to know a few workarounds: You use You can also tell the findAll to not reload in the background by adding But if you go for the always reload option, it might still give you problems if you have multiple findAll requests running simultaneously. Only an ember-data solution will fix this. Your run.next workaround could still give you problems, as no one actually knows when the findAll will return that causes the pushData. That could also be right after your run.next has started the save. PS. |
In case it's helpful, the use case that lead to the creation of this issue is having an instance-initializer that enforces the existence of certain records (creates them if they don't exist) and non-existence of others (deletes existing ones unless they meet some criterion). It would do a |
I finally dug into this and figured out what is going wrong. The crux of it is that
Why is this a problem? It is a problem is cases when the records may be deleted (modified?) between the time How can the problem be avoided / fixed? I see two approaches:
findAll_original: function(store, type /*, sinceToken */) {
// TODO: use sinceToken
this._init(store, type);
return this.get('db').rel.find(this.getRecordTypeName(type));
},
findAll_proposed: function(store, type, _neverSet, snapshotRecordArray) {
this._init(store, type);
var recordTypeName = this.getRecordTypeName(type);
var dbPromise = this.get('db').rel.find(recordTypeName);
return dbPromise.then(data => {
var states = snapshotRecordArray.snapshots().map(sar => sar._internalModel.currentState.stateName);
if (states.some(s => s.includes('deleted.inFlight'))) {
//throw Error(`Records appear to have been deleted between calling pouch adapter's findAll and its underlying tasks finishing`);
// Remove deleted records from result
var key = data[recordTypeName] ? recordTypeName : pluralize(recordTypeName);
data[key] = data[key].filter((_r, i) => !states[i].includes('deleted.inFlight'));
}
return data;
})
}, What other solutions do people think might be appropriate? Would a PR that implements the second approach be acceptable? |
I don't know what I'm missing, but it seems like it's not possible to destroy (delete & save) records, at least not when using local (
IndexedDB
) or in-memory database adapters (haven't tried others). That's hard for me to believe for an addon that apparently has significant usage & maturity, so I'd like to think I'm doing something wrong. Could someone help me figure out what it is?Complete reproduction repo is available here:
https://github.com/jacobq/ember-pouch-test-problem
Part of #235
Possibly related to #113 or #217
The text was updated successfully, but these errors were encountered: