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

Feat:split pagination and fragmentation #1294

Merged
merged 31 commits into from
May 30, 2024

Conversation

pj-cegeka
Copy link
Contributor

No description provided.

Copy link
Contributor

@Yalz Yalz left a 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)

Comment on lines 30 to 31
hibernate:
ddl-auto: update
Copy link
Contributor

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) {
Copy link
Contributor

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

Comment on lines +23 to +25
public List<BucketisedMember> addMemberToFragment(Fragment fragment, Member member,
Observation parentObservation) {
return List.of(new BucketisedMember(member.id(), fragment.getViewName(), fragment.getFragmentIdString(), member.sequenceNr()));
Copy link
Contributor

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?

Copy link
Collaborator

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.

Copy link
Collaborator

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";
Copy link
Contributor

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

Copy link
Contributor

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

Comment on lines 14 to 18
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
Copy link
Contributor

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
Copy link
Contributor

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" />
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 missing the provided configs i passed on? 😄

Comment on lines 46 to 47
fragmentSequenceRepository.saveLastProcessedSequence(new FragmentSequence(viewName, sequenceNr + 1));
sequenceNr += 1;
Copy link
Contributor

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

Copy link
Collaborator

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

Comment on lines 18 to 19
@Id
private String id;
Copy link
Contributor

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.

Copy link
Collaborator

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 {
Copy link
Collaborator

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,
Copy link
Collaborator

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?

Comment on lines +23 to +25
public List<BucketisedMember> addMemberToFragment(Fragment fragment, Member member,
Observation parentObservation) {
return List.of(new BucketisedMember(member.id(), fragment.getViewName(), fragment.getFragmentIdString(), member.sequenceNr()));
Copy link
Collaborator

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.

Comment on lines +23 to +25
public List<BucketisedMember> addMemberToFragment(Fragment fragment, Member member,
Observation parentObservation) {
return List.of(new BucketisedMember(member.id(), fragment.getViewName(), fragment.getFragmentIdString(), member.sequenceNr()));
Copy link
Collaborator

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);
Copy link
Collaborator

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

Comment on lines +56 to 57
fragmentationStrategyDecorator.addMemberToFragment(parentFragment, member,
span);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Formatting seems off

Comment on lines +40 to +43
assertThat(members.getFirst()).hasFieldOrPropertyWithValue("memberId", MEMBER_ID)
.hasFieldOrPropertyWithValue("viewName", VIEW_NAME)
.hasFieldOrPropertyWithValue("fragmentId", FRAGMENT_ID.asDecodedFragmentId())
.hasFieldOrPropertyWithValue("sequenceNr", SEQ_NR);
Copy link
Collaborator

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

Comment on lines 46 to 47
fragmentSequenceRepository.saveLastProcessedSequence(new FragmentSequence(viewName, sequenceNr + 1));
sequenceNr += 1;
Copy link
Collaborator

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

Copy link

sonarcloud bot commented May 29, 2024

@pj-cegeka pj-cegeka merged commit 6a80179 into develop May 30, 2024
3 checks passed
@pj-cegeka pj-cegeka deleted the feat/split-migration-liquibase branch May 30, 2024 11:30
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.

3 participants