Skip to content

Conversation

@hermeswaldemarin
Copy link
Contributor

Implementing Resilience and Cache Layers in Java SDK

build.gradle Outdated

ext {
VERSION = "1.5.3"
VERSION = "1.5.4"
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should bump minor version here to 1.6.0.

.whenComplete(new BiConsumer<ContextData, Throwable>() {
@Override
public void accept(ContextData contextData, Throwable throwable) {
if (throwable == null
Copy link
Contributor

Choose a reason for hiding this comment

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

What happens if throwable is not null?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nothing happens, just follow the stream calls and will fall in to the exceptionally. I'll check if the test validate this point, but I think yes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If throwable is null nothing happen in this code, the call will be sent to exceptionally step.

if (contextData != null)
return contextData;

throw (CompletionException) throwable;
Copy link
Contributor

Choose a reason for hiding this comment

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

This cast is safe because all exceptions thrown the executions through CompletableFuture are wrapped in a CompletionException, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The internal code always throw the exception with dataFuture.completeExceptionally. This will always return a CompletionException instance


public void flushCache() {
List<PublishEvent> events = localCache.retrieveEvents();
System.out.println("Sending events in cache: " + events.size());
Copy link
Contributor

Choose a reason for hiding this comment

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

Leftover log?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep deleted.

import com.absmartly.sdk.json.PublishEvent;

public interface LocalCache {
void writeEvent(PublishEvent event);
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe call these writePublishEvent and retrievePublishEvents?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

private final ObjectMapper mapper;

public AbstractCache() {
final ObjectMapper objectMapper = new ObjectMapper();
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should use the already existing interfaces here ContextEventSerializer and ContextDataSerializer.
The reason is that some users might not want to use Jackson, but use Gson or whatever else they may already have as a dependency, instead.
If we do this, then I think this abstract class is no longer necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@marcio-absmartly The problem is that we current don't have ContextDataSerializer and ContextEventDeserializer since we need to suport Serialize and Deserialize both. You think worth to create it only for this Cache purposes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done


private Connection getConnection() throws SQLException {
if (this.connection == null) {
this.connection = DriverManager.getConnection("jdbc:sqlite:absmarly.db");
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this file name be a parameter?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

implementation group: "com.fasterxml.jackson.datatype", name: "jackson-datatype-jsr310", version: jacksonDataTypeVersion
implementation group: 'org.xerial', name: 'sqlite-jdbc', version: sqliteVersion

implementation files('../libs/simpleCircuitBreaker-2.0.5.jar')
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we going to distribute this in our repository?
Can we find something on maven-central or any other repository?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately, the developer has not released it to any Maven Repo :(

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The developer didn't answer that. Let keep this way until I get a response from them.


public interface ContextEventHandler {
CompletableFuture<Void> publish(@Nonnull final Context context, @Nonnull final PublishEvent event);
void flushCache();
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems a bit out of place. The "cache" should be an implementation detail, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed

final CompletableFuture<Void> future = readyFuture_; // cache here to avoid locking
if (future != null && !future.isDone()) {
future.join();
future.whenComplete(new BiConsumer<Void, Throwable>() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this should be here for three reasons:

  1. It seems like an implementation detail of the caching mechanism.
  2. What if the user never calls waitUntilReady? i.e. the user may create the context with an already retrieved contextData.
  3. It could be done independently when the eventHandler is created, or instead, we could have a notification-like method in the interface, for example contextBecameReady() or something like that, that is called on the ContextEventHandler interface when it gets ready (not just here).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Did a change here, check if this place I put the code can have some side affect I not see.

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