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

Optimize tuple management #65

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from
Draft

Optimize tuple management #65

wants to merge 13 commits into from

Conversation

sbckr
Copy link
Member

@sbckr sbckr commented Aug 26, 2024

No description provided.

- intra-vcp/tuples endpoint now returns bytes instead of JSON (breaking change)
- tupleList is serialized to bytes

Signed-off-by: Alwin Zomotor <[email protected]>
- Castor no longer uses the TupleList class and directly returns bytes retrieved from MinIO

Signed-off-by: Alwin Zomotor <[email protected]>
Copy link

codecov bot commented Aug 26, 2024

Codecov Report

Attention: Patch coverage is 0% with 8 lines in your changes missing coverage. Please review.

Project coverage is 83.24%. Comparing base (eead173) to head (31376bc).

Files Patch % Lines
...carbynestack/castor/common/entities/TupleList.java 0.00% 8 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##             master      #65      +/-   ##
============================================
- Coverage     85.07%   83.24%   -1.83%     
+ Complexity      300      286      -14     
============================================
  Files            56       56              
  Lines          1045      979      -66     
  Branches         70       63       -7     
============================================
- Hits            889      815      -74     
- Misses          125      133       +8     
  Partials         31       31              
Flag Coverage Δ
common 73.68% <0.00%> (-1.77%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
...stack/castor/common/entities/ArrayBackedTuple.java 94.11% <ø> (ø)
...r/client/download/DefaultCastorIntraVcpClient.java 92.30% <ø> (-0.68%) ⬇️
...castor/service/config/CastorServiceProperties.java 91.66% <ø> (ø)
...service/download/DefaultTuplesDownloadService.java 93.54% <ø> (-1.69%) ⬇️
...e/persistence/cache/CreateReservationSupplier.java 100.00% <ø> (ø)
...e/persistence/cache/ReservationCachingService.java 94.89% <ø> (-0.87%) ⬇️
...e/persistence/cache/UnlockReservationSupplier.java 100.00% <ø> (ø)
.../persistence/cache/WaitForReservationCallable.java 72.22% <ø> (-1.47%) ⬇️
...stence/fragmentstore/TupleChunkFragmentEntity.java 92.50% <ø> (-0.36%) ⬇️
...ragmentstore/TupleChunkFragmentStorageService.java 91.52% <ø> (-0.42%) ⬇️
... and 5 more

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update eead173...31376bc. Read the comment docs.

@sbckr
Copy link
Member Author

sbckr commented Sep 13, 2024

There should be separate branches for the individual features

Copy link
Member Author

@sbckr sbckr left a comment

Choose a reason for hiding this comment

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

I stopped the review halfway through.

Please apologize, but it looks a bit messy. Please separate the features into individual branches and clean up the code.

I will continue afterwards.
Thank you

@@ -8,6 +8,8 @@
package io.carbynestack.castor.common.entities;

import io.carbynestack.castor.common.exceptions.CastorClientException;

import java.io.ByteArrayOutputStream;
Copy link
Member Author

Choose a reason for hiding this comment

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

unused import?

Copy link
Member Author

Choose a reason for hiding this comment

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

If not update Copyright Header

Copy link
Member Author

Choose a reason for hiding this comment

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

Please update Copyright header

@@ -70,6 +70,19 @@ public static <T extends Tuple<T, F>, F extends Field> TupleList<T, F> fromStrea
}
}

public byte[] toByteArray(){
Copy link
Member Author

Choose a reason for hiding this comment

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

This duplicates code from asChunk(UUID).
Please re-use this method accordingly.

Copy link
Member Author

Choose a reason for hiding this comment

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

Please update Copyright header

byte[].class)
.get();
long length = tupleType.getTupleSize() * count;
return TupleList.fromStream(tupleType.getTupleCls(),
Copy link
Member Author

Choose a reason for hiding this comment

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

As Tuples as mostly consumed within a stream, it may make sense to keep tuples as a stream (potentially still wrapped as a TupleList and lazily converted later if required).

Copy link
Member Author

Choose a reason for hiding this comment

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

maybe TupleList became obsolete

* @throws InterruptedException : If the fragments can not be reserved
*/
@Transactional()
public void storeReservationInDB(@NotNull Reservation reservation) throws InterruptedException {
Copy link
Member Author

Choose a reason for hiding this comment

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

Am I right that this method requires the reservation elements to be ordered by number of reserved Tuples where all elements with number of tuples < initial fragment size must be listed first.
That feels fragile especially as not properly documented (is it?)

@@ -13,6 +13,8 @@
import io.carbynestack.castor.common.exceptions.CastorClientException;
import io.carbynestack.castor.common.exceptions.CastorServiceException;
import java.util.function.Supplier;

import io.micrometer.core.annotation.Timed;
Copy link
Member Author

Choose a reason for hiding this comment

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

unused import

Copy link
Member Author

Choose a reason for hiding this comment

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

Update Copyright

@@ -62,6 +62,11 @@ public class TupleChunkFragmentEntity implements Serializable {
static final String FRAGMENT_LENGTH_COLUMN = "fragment_length";
static final String ACTIVATION_STATUS_COLUMN = "activation_status";
static final String RESERVATION_ID_COLUMN = "reservation_id";
static final String VIEW_NAME = "distributed_fragments";
static final String POD_HASH_FIELD = "pod_hash";
Copy link
Member Author

Choose a reason for hiding this comment

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

some unused statics

Copy link
Member Author

Choose a reason for hiding this comment

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

update copyright

- transaction between two threads
- now no longer checks for available tuples and will fail when trying to reserve instead, saving lots of time.

Signed-off-by: Alwin Zomotor <[email protected]>
- improved reservation locking, still needds to be fixed

Signed-off-by: Alwin Zomotor <[email protected]>
- now splits tuplechunks correctly if number of tuples % fragmentsize > 0.

Signed-off-by: Alwin Zomotor <[email protected]>
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 - for information on the respective copyright owner
* Copyright (c) 2024 - for information on the respective copyright owner
Copy link
Member Author

Choose a reason for hiding this comment

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

Copyright must be in format

...
Copyright (c) 2021 - 2024 - for information on the respective copyright owner
...

-> Copyright (c) [Year of file added] - [Year last modified] ...
if [Year of file added] is the same as [Year last modified] it is simply
-> Copyright (c) [Year of file added] ...

.retrieveSinglePartialFragment(
tupleType, oddToReserve < castorServiceProperties.getInitialFragmentSize())
.orElseThrow(
() -> new CastorServiceException(FAILED_FETCH_AVAILABLE_FRAGMENT_EXCEPTION_MSG));
Copy link
Member Author

Choose a reason for hiding this comment

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

Is there a test that ensures that all previous reservations are rolled back if there aren't enough tuples available

Copy link
Member Author

@sbckr sbckr left a comment

Choose a reason for hiding this comment

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

see individual comments

TupleChunkFragmentEntity availableFragment =
fragmentStorageService
.retrieveSinglePartialFragment(
tupleType, oddToReserve < castorServiceProperties.getInitialFragmentSize())
Copy link
Member Author

Choose a reason for hiding this comment

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

second argument preferSmall of retrieveSinglePartialFragment(TupleType tupleType, boolean preferSmall) is always true, does this make sense?

Copy link

Choose a reason for hiding this comment

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

second argument preferSmall of retrieveSinglePartialFragment(TupleType tupleType, boolean preferSmall) is always true, does this make sense?

This argument is not always true. oddToReserve may be greater than the initial Fragment size, if Castor couldn't get the whole amount of Tuples in whole fragments. This happened in my test setup because Klyshko had an off-by-one error and would save 99,999 Tuples instead of 100,000 Tuples into a tupleChunk resulting in lots of tuples getting saved in partial fragments.

Line 79 adds the amount of tuples to oddToReserve that should have been reserved as round, couldn't.


/**
* Maps the reservation elements to tuplefragments and saves them accordingly in batches to the
* RDBMS. This function assumes that all 'non-round' fragments are saved before 'round' fragments
Copy link
Member Author

Choose a reason for hiding this comment

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

what means saved? in the database?

Copy link

@zalwin zalwin Sep 25, 2024

Choose a reason for hiding this comment

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

what means saved? in the database?

Yes. Saved means saved in this context (RDBMS) means saved to postgres.

when(dedicatedTransactionServiceOptionalMock.isPresent()).thenReturn(true);
when(tupleChunkFragmentStorageServiceMock.retrieveSinglePartialFragment(tupleType, true))
.thenReturn(Optional.of(fragmentEntity));
// when(castorInterVcpClientSpy.shareReservation(any(Reservation.class))).thenReturn(false);
Copy link
Member Author

Choose a reason for hiding this comment

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

please keep code clean

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