Skip to content

fix: support for remote tx retry on the server side#2254

Merged
lvca merged 3 commits intomainfrom
remote-tx-auto-retry
Jun 11, 2025
Merged

fix: support for remote tx retry on the server side#2254
lvca merged 3 commits intomainfrom
remote-tx-auto-retry

Conversation

@lvca
Copy link
Contributor

@lvca lvca commented Jun 11, 2025

About issue #2236

What does this PR do?

A brief description of the change being made with this pull request.

Motivation

What inspired you to submit this pull request?

Related issues

A list of issues either fixed, containing architectural discussions, otherwise relevant
for this Pull Request.

Additional Notes

Anything else we should know when reviewing?

Checklist

  • I have run the build using mvn clean package command
  • My unit tests cover both failure and success scenarios

@lvca lvca added this to the 25.6.1 milestone Jun 11, 2025
@lvca lvca self-assigned this Jun 11, 2025
@lvca lvca added the enhancement New feature or request label Jun 11, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @lvca, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces support for server-side transaction retries for remote HTTP requests by modifying the HTTP handler structure to parse and pass the request payload (as a JSON object) down to the execution logic. This allows database-related handlers to configure transaction retry attempts based on the request payload.

Highlights

  • HTTP Handler Signature Update: Modified the base AbstractServerHttpHandler and its subclasses to accept a JSONObject payload parameter in the execute method. This allows handlers to easily access structured request body data.
  • Payload Parsing in Base Handler: The AbstractServerHttpHandler now parses the request body into a JSONObject before calling the specific handler's execute method, centralizing this logic.
  • Server-Side Transaction Retry: Updated DatabaseAbstractHandler to read an optional attempts parameter from the request payload and pass it to the database.transaction method, enabling server-side retries for database operations initiated via HTTP.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configureGemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for remote transaction retries on the server side by passing a JSONObject payload (which can contain retry attempts) to various HTTP handlers. The core logic for handling retries within transactions is updated in DatabaseAbstractHandler. The changes also include some refactoring of payload parsing in AbstractServerHttpHandler and its consumers, along with minor style adjustments like wildcard imports in several files.

My review focuses on adherence to common Java best practices and the Google Java Style Guide (for aspects like import statements), code maintainability (addressing duplication), and minor code cleanliness issues.

Comment on lines +45 to +46
import java.util.concurrent.atomic.*;
import java.util.logging.*;
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

According to the Google Java Style Guide, wildcard imports are generally discouraged except for specific cases like java.util.* or java.io.*. For java.util.concurrent.atomic and java.util.logging, it's preferable to use specific imports to improve clarity and avoid potential namespace collisions.

For java.util.concurrent.atomic.*, only AtomicReference appears to be used from this package in this file.
For java.util.logging.*, only Level appears to be used from this package in this file (as LogManager is imported from com.arcadedb.log.LogManager).

Suggested change
import java.util.concurrent.atomic.*;
import java.util.logging.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;

Comment on lines +95 to +122
boolean finalAtomicTransaction = atomicTransaction;
if (activeSession != null) {
// EXECUTE THE CODE LOCKING THE CURRENT SESSION. THIS AVOIDS USING THE SAME SESSION FROM MULTIPLE THREADS AT THE SAME TIME
activeSession.execute(user, () -> {
response.set(execute(exchange, user, database));
if (finalAtomicTransaction) {
database.transaction(() -> {
try {
response.set(execute(exchange, user, database, payload));
} catch (Exception e) {
throw new TransactionException("Error on executing command", e);
}
}, false, attempts);
} else
response.set(execute(exchange, user, database, payload));
return null;
});
else
response.set(execute(exchange, user, database));
} else {
if (finalAtomicTransaction) {
database.transaction(() -> {
try {
response.set(execute(exchange, user, database, payload));
} catch (Exception e) {
throw new TransactionException("Error on executing command", e);
}
}, false, attempts);
} else
response.set(execute(exchange, user, database, payload));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The logic for executing the command, potentially within a transaction, is duplicated in the if (activeSession != null) block and the else block. This makes the method harder to read and maintain.

Consider extracting the common execution logic into a private helper method. This helper method could take parameters like exchange, user, database, payload, finalAtomicTransaction, attempts, and response.

For example, a helper method could look like:

private void executeCommandWithOptionalTransaction(
    HttpServerExchange exchange, 
    ServerSecurityUser user, 
    DatabaseInternal database, 
    JSONObject payload, 
    boolean isTransactional, 
    int attempts, 
    AtomicReference<ExecutionResponse> responseRef) throws Exception {

    if (isTransactional && database != null) {
        database.transaction(() -> {
            try {
                responseRef.set(execute(exchange, user, database, payload));
            } catch (Exception e) {
                throw new TransactionException("Error on executing command", e);
            }
        }, false, attempts);
    } else {
        responseRef.set(execute(exchange, user, database, payload));
    }
}

This would simplify the main execute method significantly.

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.logging.*;
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Consistent with the Google Java Style Guide, prefer specific imports over wildcard imports for java.util.logging.*. In this file, only Level seems to be used from java.util.logging (as LogManager is imported from com.arcadedb.log.LogManager).

Suggested change
import java.util.logging.*;
import java.util.logging.Level;

import java.util.logging.Level;
import java.io.*;
import java.util.*;
import java.util.logging.*;
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Consistent with the Google Java Style Guide, prefer specific imports over wildcard imports for java.util.logging.*. In this file, only Level seems to be used from java.util.logging (as LogManager is imported from com.arcadedb.log.LogManager).

Suggested change
import java.util.logging.*;
import java.util.logging.Level;

@lvca lvca merged commit bf046b8 into main Jun 11, 2025
10 of 11 checks passed
@lvca lvca deleted the remote-tx-auto-retry branch June 11, 2025 19:18
@codacy-production
Copy link

codacy-production bot commented Jun 11, 2025

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
Report missing for bea30191 73.68%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (bea3019) Report Missing Report Missing Report Missing
Head commit (632536f) 72425 45418 62.71%

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#2254) 38 28 73.68%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

Footnotes

  1. Codacy didn't receive coverage data for the commit, or there was an error processing the received data. Check your integration for errors and validate that your coverage setup is correct.

robfrank pushed a commit that referenced this pull request Jun 17, 2025
* fix: support for remote tx retry on the server side

About issue #2236

* Fixed empty payload

* fix: json parsing as payload

(cherry picked from commit bf046b8)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant