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

Repository.latest_version() considering deleted versions #555

Merged
merged 1 commit into from Feb 24, 2020

Conversation

fao89
Copy link
Member

@fao89 fao89 commented Feb 19, 2020

https://pulp.plan.io/issues/6147
closes #6147

Please be sure you have read our documentation on creating PRs:
https://docs.pulpproject.org/contributing/pull-request-walkthrough.html

@@ -740,6 +740,9 @@ def delete(self, **kwargs):
# and delete the version
repo_relations.filter(version_added=self).delete()
repo_relations.filter(version_removed=self).update(version_removed=None)
if self.number == self.repository.last_version:
self.repository.last_version = self.number - 1
self.repository.save()
Copy link
Contributor

@dralley dralley Feb 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't tested this out, but could you check this scenario? What happens if you create 3 new repository versions, so you have:

0, 1, 2, 3
repository.last_version = 3

If you delete 3 and then 2 you would probably get the correct result:

0, 1,
repository.last_version = 1

But if you delete 2 and then 3, then I think with this algorithm you would get:

0, 1
repository.last_version = 2

I could be wrong, it's just an edge case we should check :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will write a test for it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably just 2 versions is enough to test this, version 1 isn't really doing much as-is.

Copy link
Contributor

@dralley dralley Feb 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this also brings a question to mind -- do we want repository version numbers to be re-usable? Because if we reset last_version appropriately, and we also set number of the next version as last_version + 1 , then that means that it will be possible to overwrite the value of ${REPO_HREF}/versions/2/ with a new version 2 that contains different content. The version number won't be monotonically increasing.

Copy link
Contributor

@dralley dralley Feb 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solution from IRC:

  • Rename Repository.last_version to Repository.next_version and do a data migration to add +1 to its value
  • When creating a new repository version, use the value of Repository.next_version and if it is successfully created increment this value.
  • To determine the latest repository version, do this (and see if we can get rid of that custom field)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds right to me. Does this change the REST API ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dkliban it shouldn't. We don't expose that field.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't, no. last_version isn't serialized and next_version doesn't need to be either.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! thanks for confirming that.

@fao89 fao89 force-pushed the 6147 branch 4 times, most recently from cfd5e91 to 260ddd4 Compare February 19, 2020 21:28
@fao89 fao89 changed the title Deleted versions update Repository.last_version Repository.latest_version() considering deleted versions Feb 19, 2020
Repository = apps.get_model('core', 'Repository')
if 'last_version' in dir(Repository):
for repository in Repository.objects.all().only('last_version'):
repository.last_version = int(repository.last_version) + 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you could try something like this, it might be more efficient: https://stackoverflow.com/questions/12661253/how-to-bulk-update-with-django

The main benefit though is that I think .save() would change the last_updated timestamp and while I don't think that's necessarily a problem we should avoid it if we can help it.

@@ -93,10 +92,8 @@ def new_version(self, base_version=None):
with transaction.atomic():
version = RepositoryVersion(
repository=self,
number=int(self.last_version) + 1,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love that this logic was made simpler!

@@ -748,7 +760,7 @@ def delete(self, **kwargs):
RepositoryContent.objects.filter(version_removed=self) \
.update(version_removed=None)
CreatedResource.objects.filter(object_id=self.pk).delete()
self.repository.last_version = self.number - 1
self.repository.next_version = self.number - 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this line should be deleted entirely. We should only increment repository.next_version once the repository version has been successfully created and finalized, so we shouldn't ever need to decrement it. If the repository version wasn't completed then it shouldn't have been incremented so we shouldn't need to decrement it here.

adding = self._state.adding
super().save(*args, **kwargs)
if adding:
self.repository.next_version = self.number + 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@dralley dralley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fabricio-aguiar This looks excellent, thank you!

I think this should have a review from at least one other person, David/Brian/Dennis

# re: https://pulp.plan.io/issues/6147
with transaction.atomic():
Repository = apps.get_model('core', 'Repository')
if 'last_version' in dir(Repository):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not totally sure I understand what the conditional does, do some Repository objects not have this field?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is for not breaking if for any reason someone re-run the migration, because after migration last_version will no longer exist

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's possible to re-run a migration unless you go out of your way to do so, the most recent migration is stored somewhere and it picks up from there afterwards

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not possible to rerun a migration because we don't provide downgrade migrations. Is this part of the logic still needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just added it in case someone would rerun, since it is not possible to rerun, it is not needed

Copy link
Contributor

@daviddavis daviddavis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -0,0 +1 @@
Replacing Repository.last_version with Repository.next_version
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rephrase this some? Can it be Renaming Repository.last_version to Repository.next_version

Copy link
Member

@bmbouter bmbouter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @fabricio-aguiar this looks great!

fao89 added a commit to fao89/pulp_rpm that referenced this pull request Feb 21, 2020
[noissue]
Notice this with pulp/pulpcore#555
Renaming last_version was breaking pulp_rpm
fao89 added a commit to fao89/pulp_rpm that referenced this pull request Feb 21, 2020
fao89 added a commit to fao89/pulp_rpm that referenced this pull request Feb 21, 2020
fao89 added a commit to fao89/pulp_rpm that referenced this pull request Feb 21, 2020
@daviddavis daviddavis merged commit 7be835f into pulp:master Feb 24, 2020
daviddavis pushed a commit to pulp/pulp_rpm that referenced this pull request Feb 24, 2020
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.

None yet

5 participants