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

Introduce versions formatter for the schema dumper #53797

Merged

Conversation

fatkodima
Copy link
Member

Follow up to #44363 (cc @ghiculescu).

Previously, the versions were sorted in decreasing order and new added to the top of the list. Within large-enough teams, this can cause many merge conflicts near the top of this list. Within my company, we have lots of developers pushing lots of schema changes and half of the time someone merges a PR, lots of existing PRs now have conflicts with the master.

Now, the versions are sorted by their reverse representations (20241201183002 -> 20038110214202), in decreasing (can be increasing, does not matter, but to be consistent with the previous implementation) order. This will greatly reduce the likelihood of merge conflicts as now new versions can be inserted at any place in the existing list. I did a simple calculation and while before we had a likelihood of conflict within a list of, say 5 top elements (20%), now - within a whole list of 600+ items (0.1%).

I also added a comment with reversed version representation for each version within dumped structure.sql file for people to more easily solve the merge conflicts. But we can remove this and add a comment at the top of the INSERT describing the algorithm.

For existing apps, there will be a large diff the next time structure.sql is generated.

@ghiculescu
Copy link
Member

I love this idea!

IMO the comment is a bit confusing unless you already know about the algorithm.

@fatkodima fatkodima force-pushed the change-structure-dump-versions-ordering branch from 15dfdcb to 081880b Compare December 1, 2024 23:01
@fatkodima
Copy link
Member Author

Agree, changed to print only a comment at the top of the list.

@byroot
Copy link
Member

byroot commented Dec 2, 2024

I'm not too sure how I feel about that.

I'm sympathetic to the desire of reducing conflicts, but it feels weird to have these versions ordered in a seemingly arbitrary fashion. I'll try to seek a second opinion.

@fatkodima
Copy link
Member Author

Another alternative is the ability for users to provide a custom proc, which will be used for sorting these versions.

@@ -32,6 +32,7 @@ def test_dump_schema_information_outputs_lexically_reverse_ordered_versions_rega

schema_info = ActiveRecord::Base.lease_connection.dump_schema_information
expected = <<~STR
-- Versions are sorted by reverse representations of numbers (abc -> cba) in descending order.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
-- Versions are sorted by reverse representations of numbers (abc -> cba) in descending order.
-- Versions are sorted by reverse representations of numbers (20241225000000 -> 00000052214202) in descending order.

@eileencodes
Copy link
Member

I'm sympathetic to the problem but I really don't like this solution. Reversing the strings is just confusing and I can imagine both beginners and seasoned Rails devs getting stuck on this. If we merge this we'll get endless bug reports and complaints.

@fatkodima
Copy link
Member Author

Wdyt about my alternative idea

Another alternative is the ability for users to provide a custom proc, which will be used for sorting these versions.

so people can be able to configure their custom logic? And we preserve the original implementation by default.

@ghiculescu
Copy link
Member

If we merge this we'll get endless bug reports and complaints.

I'm skeptical. I am going to monkey patch this into our codebase, and see if anyone (~50 devs) notices or asks.

@ghiculescu
Copy link
Member

^ A week later nobody has asked about it (as far as I'm aware) and we're definitely seeing less merge conflicts.

@ghiculescu
Copy link
Member

image

@byroot
Copy link
Member

byroot commented Dec 12, 2024

This was the reactions when the order was reversed: #44363

@fatkodima
Copy link
Member Author

If this PR is implemented in alternative way, for example, providing users a proc to configure, for example config.active_record.structure_versions_sort = ->(a, b) { b <=> a }, we can preserve the current behaviour, for not happy people from the linked PR to use ->(a, b) { a <=> b } to return to the previous behavior, and for the proposal in this PR to use the behaviour we want ->(a, b) { b.to_s.reverse <=> a.to_s.reverse }.

@byroot
Copy link
Member

byroot commented Dec 12, 2024

If this PR is implemented in alternative way, for example, providing users a proc to configure,

@eileencodes @matthewd thoughts? I'm not against it, but it's yet another super obscure config.

@byroot
Copy link
Member

byroot commented Dec 19, 2024

for example, providing users a proc to configure, for example config.active_record.structure_versions_sort = ->(a, b) { b <=> a }

I can be convinced to offer some way to customize this, but I wonder if rather than just exposing a sort proc, we might not as well refactor insert_versions_sql out so it's implemented by a class that you can substitue, e.g (untested pseudo-code).

def insert_versions_sql
  self.class.schema_version_inserter.generate(pool.schema_migration)
end

Then you get the flexibility to order however you want, but also include some comments, and even fetch the list of versions differently.

@fatkodima fatkodima force-pushed the change-structure-dump-versions-ordering branch from 081880b to 6c18dc7 Compare December 20, 2024 00:55
@rails-bot rails-bot bot added the docs label Dec 20, 2024
@fatkodima fatkodima changed the title Change the order of INSERT statements in structure.sql dumps Introduce versions formatter for the schema dumper Dec 20, 2024
@fatkodima
Copy link
Member Author

Updated with the suggestion for a separate class.

@fatkodima fatkodima force-pushed the change-structure-dump-versions-ordering branch from 6c18dc7 to 7bdd0df Compare December 20, 2024 01:02
@fatkodima fatkodima force-pushed the change-structure-dump-versions-ordering branch from 7bdd0df to 0cc1842 Compare December 20, 2024 01:10
@byroot byroot merged commit 0bded31 into rails:main Dec 27, 2024
3 checks passed
to change the default behavior:

```ruby
class CustomSchemaVersionsFormatter
Copy link
Contributor

Choose a reason for hiding this comment

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

I've just tried this snippet and it's missing

   private attr_reader :connection
   def initialize(connection)
        @connection = connection
   end

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
Member Author

Choose a reason for hiding this comment

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

oops, #54054

@fatkodima fatkodima deleted the change-structure-dump-versions-ordering branch December 27, 2024 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants