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

Rework Update JSON encoders and decoders #3261

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

fthomas
Copy link
Member

@fthomas fthomas commented Jan 7, 2024

This is an attempt to clarify the various Encoder and Decoder instances that make up Encoder[Update] and Decoder[Update] that are used by the PullRequestRepository for writing/reading updates to/from disk.

I had a hard time understanding what was going on because

  • nearly all of the instances are implicit (for derivation) but only the instances for Update are used by other parts of the program
  • semi-derivation was mixed with manual modifications
  • decoders for compatibility with old caches depend on derivation and are defined ad-hoc

In this change I tried to bring more clarity to these instances by

  • giving compatibility decoders their own name
  • forgoing semi-derivation and define all instances manually. IMHO this makes it easier to evolve them if there are compatibility constraints because of old caches
  • making every instance except Encoder[Update] and Decoder[Update] private and non-implicit
  • only testing them via the public Encoder[Update] and Decoder[Update] instances

This might be a controversial change and I ackknowledge that one gains more understanding by doing this rework. I'm therefore biased that these changes actually clarify anything. I'm fine with letting this age for a while before merging to see if I still feel this is an improvement then.

This is an attempt to clarify the various `Encoder` and `Decoder` instances
that make up `Encoder[Update]` and `Decoder[Update]` that are used by the
`PullRequestRepository` for writing/reading updates to/from disk.

I had a hard time understanding what was going on because
* nearly all of the instances are implicit (for derivation) but only the
  instances for `Update` are used by other parts of the program
* semi-derivation was mixed with manual modifications
* decoders for compatibility with old caches depend on derivation and
  are defined ad-hoc

In this change I tried to bring more clarity to these instances by
* giving compatibility decoders their own name
* forgoing semi-derivation and define all instances manually. IMHO this
  makes it easier to evolve them if there are compatibility constraints
  because of old caches
* making every instance except `Encoder[Update]` and `Decoder[Update]`
  private and non-implicit
* only testing them via the public `Encoder[Update]` and `Decoder[Update]`
  instances

This might be a controversial change and I ackknowledge that one gains
more understanding by doing this rework. I'm therefore biased that these
changes actually clarify anything. I'm fine with letting this age for a
while before merging to see if I still feel this is an improvement then.
Copy link

codecov bot commented Jan 7, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (600d2a3) 91.18% compared to head (026eb23) 91.25%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3261      +/-   ##
==========================================
+ Coverage   91.18%   91.25%   +0.06%     
==========================================
  Files         167      167              
  Lines        3405     3432      +27     
  Branches      306      304       -2     
==========================================
+ Hits         3105     3132      +27     
  Misses        300      300              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@alejandrohdezma
Copy link
Member

@fthomas do we still need to keep compatibility for old caches? wouldn't have those already expire and one with the new encoder be created?

@fthomas
Copy link
Member Author

fthomas commented Jan 7, 2024

wouldn't have those already expire and one with the new encoder be created?

This is true for caches that have been updated since #2898 (which was the last change to the Update encoding). But we can't be sure there are no older caches lingering around that will be used again in the future. If we break compatibility with those, the people who run the Scala Steward instance need to remove these old caches for it to work again. I know that this situation is very unlikely, but is unsatisfactory that it could exist.

On the other hand it is very tempting to just semi-derive all our instances again and remove the compatibility decoders. It would simplify that part of the code base as much as possible.

@alejandrohdezma
Copy link
Member

wouldn't have those already expire and one with the new encoder be created?

This is true for caches that have been updated since #2898 (which was the last change to the Update encoding). But we can't be sure there are no older caches lingering around that will be used again in the future. If we break compatibility with those, the people who run the Scala Steward instance need to remove these old caches for it to work again. I know that this situation is very unlikely, but is unsatisfactory that it could exist.

On the other hand it is very tempting to just semi-derive all our instances again and remove the compatibility decoders. It would simplify that part of the code base as much as possible.

That makes sense. Thanks for the clarification 😊

Copy link
Member

@mzuehlke mzuehlke left a comment

Choose a reason for hiding this comment

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

This brings consistency to all the different version 👍

The other alternative would be to have matching case classes for all different versions, then use semiauto and convert afterwards into the current version.
But I have the feeling that your version is easier to understand.

@fthomas
Copy link
Member Author

fthomas commented Jan 8, 2024

The other alternative would be to have matching case classes for all different versions, then use semiauto and convert afterwards into the current version.

That sounds interesting! I'll give it a try.

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.

3 participants