-
Notifications
You must be signed in to change notification settings - Fork 10
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
Feat:split pagination and fragmentation #1294
Conversation
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.
Some general remarks that I don't find the right place for it:
- I was thinking that the split would maybe mean a separate module since i see no logic that should be shared between these two functionalities? (this would mean that my table name suggestion needs to be modified of course)
- The current PAginationService seems quite complex with the isRunning, stopTask, ... and should in the next iteration best use Spring Batch (this however doesn't stop this PR)
docker-compose/server.config.yml
Outdated
hibernate: | ||
ddl-auto: update |
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.
since liquibase will take care of our tables, this should be dropped. (also from the docs)
MemberRetriever memberRetriever, | ||
FragmentSequenceRepository fragmentSequenceRepository) { | ||
MemberRetriever memberRetriever, | ||
FragmentSequenceRepository fragmentSequenceRepository, BucketisedMemberSaverImpl bucketisedMemberSaver) { |
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.
If you could use the Interface instead of the implementation here..?
public List<BucketisedMember> addMemberToFragment(Fragment fragment, Member member, | ||
Observation parentObservation) { | ||
return List.of(new BucketisedMember(member.id(), fragment.getViewName(), fragment.getFragmentIdString(), member.sequenceNr())); |
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.
so if i get this right, the FragmentationStrategyImpl is the lowest level of fragmentation which was actually the process that did the pagination.. How come this is then still in place?
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 way I see it, was this lowest level impl responsible for saving it to the repository and letting the rest of the application know the fragmentation of the member is completed. However, this is moved to the BucketisedMemberSaverImpl
which does this job now and the only job this impl does, is mapping the member to a singleton BucketisedMember list.
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.
However, I am not a fan of these changes, as it seems to break the decorator pattern and a lot of refactoring was required, as the method now needs to return the list rather than handling the saving into the repository and publishing the event by the lowest level impl.
In addition due to these changes, the injected fields are not used anymore
@Index(columnList = "sequenceNr") | ||
}) | ||
public class MemberBucketisationEntity { | ||
public static final String BUCKETISATION = "bucketisation"; |
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.
can you prefix this ? fragmentation_bucket
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.
also in general, i'd call in memberBucketEntity since otherwise it sounds too much like the process instead of a table
<properties> | ||
<maven.compiler.source>21</maven.compiler.source> | ||
<maven.compiler.target>21</maven.compiler.target> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
</properties> |
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.
please exclude these properties :)
@@ -0,0 +1,12 @@ | |||
create table public.bucketisation |
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.
Would reccomend it to split creation off in the XML approach, looks a bit cleaner :)
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd"> | ||
|
||
<include file="/db/changelog/3_0_1/bucketisation.sql" /> |
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.
I'm missing the provided configs i passed on? 😄
fragmentSequenceRepository.saveLastProcessedSequence(new FragmentSequence(viewName, sequenceNr + 1)); | ||
sequenceNr += 1; |
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.
if you do sequenceNr++, the increment will not be added before the computation of the FragmentSequence i believe
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.
I believe so too, however, instead of sequenceNr++
, ++sequenceNr
could be used, which should do the addition beforehand
@Id | ||
private String id; |
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.
if not using the String as an identifier, I'd use a Auto increment value as ID and store the bucket name as a separate value. This mainly has impact on peformance when it comes to indexing.
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.
As this is an entity, a custom equals and hashcode impl should be provided that only checks the ids
import java.util.List; | ||
|
||
@Component | ||
public class BucketisedMemberSaverImpl { |
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.
I think it is odd that the class name contains the suffix "Impl" when it does not implement an interface. I would suggest to either extract an interface from this or remove the suffix
@@ -24,23 +25,25 @@ public class FragmentationStrategyExecutor { | |||
private final ObservationRegistry observationRegistry; | |||
private final MemberRetriever memberRetriever; | |||
private final FragmentSequenceRepository fragmentSequenceRepository; | |||
private final BucketisedMemberSaverImpl bucketisedMemberSaver; | |||
private boolean isExecutorActive = true; | |||
|
|||
public FragmentationStrategyExecutor(ViewName viewName, |
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.
A new sonar will be introduced, as this constructor has more than 7 parameters, so could be either suppressed or fixed please?
public List<BucketisedMember> addMemberToFragment(Fragment fragment, Member member, | ||
Observation parentObservation) { | ||
return List.of(new BucketisedMember(member.id(), fragment.getViewName(), fragment.getFragmentIdString(), member.sequenceNr())); |
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 way I see it, was this lowest level impl responsible for saving it to the repository and letting the rest of the application know the fragmentation of the member is completed. However, this is moved to the BucketisedMemberSaverImpl
which does this job now and the only job this impl does, is mapping the member to a singleton BucketisedMember list.
public List<BucketisedMember> addMemberToFragment(Fragment fragment, Member member, | ||
Observation parentObservation) { | ||
return List.of(new BucketisedMember(member.id(), fragment.getViewName(), fragment.getFragmentIdString(), member.sequenceNr())); |
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.
However, I am not a fan of these changes, as it seems to break the decorator pattern and a lot of refactoring was required, as the method now needs to return the list rather than handling the saving into the repository and publishing the event by the lowest level impl.
In addition due to these changes, the injected fields are not used anymore
|
||
FragmentationStrategy fragmentationStrategy = fragmentationStrategyCreator | ||
.createFragmentationStrategyForView(viewSpecification); | ||
|
||
assertEquals(paginationFragmentationStrategy, fragmentationStrategy); | ||
assertThat(fragmentationStrategy).isOfAnyClassIn(FragmentationStrategyImpl.class); |
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.
As you are only checking for one class type, I would suggest to use isInstanceOf()
instead of isOfAnyClassIn()
fragmentationStrategyDecorator.addMemberToFragment(parentFragment, member, | ||
span); |
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.
Formatting seems off
assertThat(members.getFirst()).hasFieldOrPropertyWithValue("memberId", MEMBER_ID) | ||
.hasFieldOrPropertyWithValue("viewName", VIEW_NAME) | ||
.hasFieldOrPropertyWithValue("fragmentId", FRAGMENT_ID.asDecodedFragmentId()) | ||
.hasFieldOrPropertyWithValue("sequenceNr", SEQ_NR); |
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.
A little suggestion: an expectedBucketisedMember could be declared with all these properties and then the assertion could look like this:
assertThat(members.getFirst())
.usingRecursiveComparison() // this makes sure all fields are compared
.isEqualTo(expectedBucketisedMember);
fragmentSequenceRepository.saveLastProcessedSequence(new FragmentSequence(viewName, sequenceNr + 1)); | ||
sequenceNr += 1; |
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.
I believe so too, however, instead of sequenceNr++
, ++sequenceNr
could be used, which should do the addition beforehand
Quality Gate passedIssues Measures |
No description provided.