Skip to content
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

Merged

Conversation

fenekku
Copy link
Collaborator

@fenekku fenekku commented Jun 30, 2023

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, so edit 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 the next_draft_id stored in the parent. Because next_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 that next_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).

@@ -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:
Copy link
Collaborator Author

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.

@fenekku fenekku force-pushed the app_rdm_2197_fix_new_version_bug branch 4 times, most recently from 8eb1259 to 1eeef7d Compare July 7, 2023 12:48
@fenekku fenekku changed the title [WIP] api: don't override next version with new draft api: don't override next version with new draft Jul 7, 2023
@fenekku
Copy link
Collaborator Author

fenekku commented Jul 7, 2023

Since the failing tests are due to #192 and may be remedied by #231, I might as well put this up for review.

@fenekku fenekku requested review from ppanero and zzacharo July 7, 2023 13:51
@fenekku
Copy link
Collaborator Author

fenekku commented Jul 7, 2023

@Samk13 can you give this a review too since it addresses a problem you had too?

tests/records/test_api.py Outdated Show resolved Hide resolved
@fenekku fenekku force-pushed the app_rdm_2197_fix_new_version_bug branch 3 times, most recently from 85044a4 to 68529b2 Compare July 7, 2023 14:26
# Classic draft of published record having been cleaned up scenario
record_1 = Record.publish(Draft.create({}))
db.session.commit()
Draft.cleanup_drafts(timedelta(0))
Copy link
Collaborator Author

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).

Comment on lines +146 to +148
parent = ParentRecord.create({})
record_2 = Record.create({}, parent=parent)
record_2.register()
Copy link
Collaborator Author

@fenekku fenekku Jul 7, 2023

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.

@Samk13
Copy link
Member

Samk13 commented Jul 7, 2023

@fenekku It's awesome that you've resolved this tricky issue!
Unfortunately, I'm on holiday and won't be able to review the fix until I return in a month.
I recall that it was challenging to recreate but I'll definitely add it to my todos when I am back!

@fenekku fenekku requested a review from zzacharo July 10, 2023 21:01
@tmorrell tmorrell requested a review from ntarocco August 1, 2023 17:15
@ntarocco ntarocco force-pushed the app_rdm_2197_fix_new_version_bug branch from 68529b2 to 40d9718 Compare August 11, 2023 16:45
Copy link
Contributor

@ntarocco ntarocco left a 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! 👏🏼

@ntarocco ntarocco merged commit 8a42ed1 into inveniosoftware:master Aug 11, 2023
6 checks passed
@fenekku fenekku deleted the app_rdm_2197_fix_new_version_bug branch August 11, 2023 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Inconsistent NewVersion button behavior on some records
4 participants