-
Notifications
You must be signed in to change notification settings - Fork 40
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
api: don't override next version with new draft #232
api: don't override next version with new draft #232
Conversation
@@ -199,8 +199,8 @@ def post_create(self, record): | |||
# The parent record is created on pre_create. | |||
versions = self.obj(record) | |||
if self._create and self._set_next: | |||
# if fork is none - it's a new? | |||
versions.set_next() | |||
if not record.is_published: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the fix. When interacting with the site in the browser it fixes the issue.
8eb1259
to
1eeef7d
Compare
@Samk13 can you give this a review too since it addresses a problem you had too? |
85044a4
to
68529b2
Compare
# Classic draft of published record having been cleaned up scenario | ||
record_1 = Record.publish(Draft.create({})) | ||
db.session.commit() | ||
Draft.cleanup_drafts(timedelta(0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The most typical case (but relies on cleanup_drafts).
parent = ParentRecord.create({}) | ||
record_2 = Record.create({}, parent=parent) | ||
record_2.register() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wider case that covers the above if cleanup_drafts works correctly and covers other scenarios e.g. direct forced deletion etc . In other words, anything that gets us to a published record without a draft.
@fenekku It's awesome that you've resolved this tricky issue! |
68529b2
to
40d9718
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for fixing this nasty one! 👏🏼
closes inveniosoftware/invenio-app-rdm#2197
Although small, the fix has a larger context to understand. When a record is published, its draft is soft-deleted in the db until
cleanup_drafts
hard deletes it. When that happens, the published record has no associated draft anymore, soedit
will create a completely new draft for it. However, that record may have a new version already (this is a fairly common occurrence in a running instance), so the new draft must not overwrite the reference to thenext_draft_id
stored in the parent. Becausenext_draft_id
is used both to refer to a record's next version and a never published before draft's own id, we get interference. By checking if we are in the case of a record that has been published (only records that can have a new version) versus a record that has not, we can appropriately set thatnext_draft_id
.Another challenge with this PR was testing it. When trying to test this at the service level, we encounter OpenSearch's delete behavior (link to ElasticSearch but it applies to OpenSearch): the deleted document's
version
is kept around for 60s after deletion to overcome concurrency issues: Opensearch keeps a tombstone of deleted documents around and lets you reindex to a deleted document. So the version needs to stick around a little to make sure an update sent just before deletion was processed doesn't create a new record (updates can create new records in ES/OS).