[IMP] mail: completely clean records after deletion
This will reduce memory leaks. Side-effect of this PR: Accessing a field after the record is deleting is no longer supported. It was never meant to be, but some async code relied on this behavior to check the (non-)existence of relation fields, with an implicit check on the current record existence. -> After this PR, the existence check of current record needs to be explicit, before accessing any field. Part of task-2850875 Part-of: odoo/odoo#90934
This commit is contained in:
@@ -138,8 +138,7 @@ export class ModelManager {
|
||||
/**
|
||||
* Create the messaging singleton record.
|
||||
*/
|
||||
const messaging = this.models['Messaging'].insert(values);
|
||||
Object.assign(odoo.__DEBUG__, { messaging });
|
||||
this.models['Messaging'].insert(values);
|
||||
this.messagingCreatedPromise.resolve();
|
||||
await this.messaging.start();
|
||||
this.messagingInitializedPromise.resolve();
|
||||
@@ -204,8 +203,7 @@ export class ModelManager {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
exists(model, record) {
|
||||
const existingRecord = model.__records[record.localId];
|
||||
return Boolean(existingRecord && existingRecord === record);
|
||||
return Boolean(record.localId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -655,7 +653,7 @@ export class ModelManager {
|
||||
get: function getFromProxy(record, prop) {
|
||||
if (
|
||||
!model.__fieldMap[prop] &&
|
||||
!['_super', 'then'].includes(prop) &&
|
||||
!['_super', 'then', 'localId'].includes(prop) &&
|
||||
typeof prop !== 'symbol' &&
|
||||
!(prop in record)
|
||||
) {
|
||||
@@ -736,6 +734,9 @@ export class ModelManager {
|
||||
if (field.fieldType === 'relation') {
|
||||
// ensure inverses are properly unlinked
|
||||
field.parseAndExecuteCommands(record, unlinkAll(), { allowWriteReadonly: true });
|
||||
if (!record.exists()) {
|
||||
return; // current record might have been deleted from causality
|
||||
}
|
||||
}
|
||||
}
|
||||
this._createdRecordsComputes.delete(record);
|
||||
@@ -756,7 +757,10 @@ export class ModelManager {
|
||||
infoList,
|
||||
});
|
||||
}
|
||||
delete record.__values;
|
||||
delete record.__listeners;
|
||||
delete model.__records[record.localId];
|
||||
delete record.localId;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1215,6 +1219,10 @@ export class ModelManager {
|
||||
for (const field of model.__fieldList) {
|
||||
Object.defineProperty(model.prototype, field.fieldName, {
|
||||
get: function getFieldValue() { // this is bound to record
|
||||
if (!this.exists()) {
|
||||
// Deprecated, allows reading fields on deleted records. Use exists() instead.
|
||||
return undefined;
|
||||
}
|
||||
if (this.modelManager._listeners.size) {
|
||||
if (!this.modelManager._listenersObservingLocalId.has(this.localId)) {
|
||||
this.modelManager._listenersObservingLocalId.set(this.localId, new Map());
|
||||
|
||||
@@ -65,9 +65,11 @@ registerModel({
|
||||
if (this._isDragSourceExternalFile(ev.dataTransfer)) {
|
||||
if (this.chatterOwner) {
|
||||
await this.chatterOwner.fileUploader.uploadFiles(ev.dataTransfer.files);
|
||||
return;
|
||||
}
|
||||
if (this.composerViewOwner) {
|
||||
await this.composerViewOwner.fileUploader.uploadFiles(ev.dataTransfer.files);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -14,10 +14,14 @@ registerModel({
|
||||
name: 'Messaging',
|
||||
identifyingFields: [],
|
||||
lifecycleHooks: {
|
||||
_created() {
|
||||
odoo.__DEBUG__.messaging = this;
|
||||
},
|
||||
_willDelete() {
|
||||
if (this.env.services['legacy_bus_service']) {
|
||||
this.env.services['legacy_bus_service'].off('window_focus', null, this._handleGlobalWindowFocus);
|
||||
}
|
||||
delete odoo.__DEBUG__.messaging;
|
||||
},
|
||||
},
|
||||
recordMethods: {
|
||||
|
||||
@@ -292,6 +292,9 @@ registerModel({
|
||||
return;
|
||||
}
|
||||
const fetchedMessages = await this._loadMessages();
|
||||
if (!this.exists()) {
|
||||
return;
|
||||
}
|
||||
for (const threadView of this.threadViews) {
|
||||
threadView.addComponentHint('messages-loaded', { fetchedMessages });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user