Skip to content

gRPC support for ArcadeDB#2462

Closed
oc007us wants to merge 37 commits intoArcadeData:mainfrom
oc007us:main
Closed

gRPC support for ArcadeDB#2462
oc007us wants to merge 37 commits intoArcadeData:mainfrom
oc007us:main

Conversation

@oc007us
Copy link

@oc007us oc007us commented Aug 31, 2025

What does this PR do?

This PR introduces full gRPC support for ArcadeDB, providing a strongly-typed, high-performance API for remote access to the database.

Key highlights include:

  • Streaming query execution with multiple retrieval modes:

    • CURSOR – existing behavior, iterating and streaming results as they are retrieved.
    • MATERIALIZE_ALL – materializes all results before streaming in batches.
    • PAGED – reissues queries per batch using LIMIT/SKIP for efficient paging.
  • Insert operations:

    • BulkInsert – single request for large batch inserts.
    • InsertStream – client-streaming bulk insert with server-side batching and acknowledgements.
    • InsertBidirectional – full duplex insert mode with per-batch acknowledgements and commit/rollback control.
  • Record operations:

    • Create, update, and lookup records with schema-aware property handling (including embedded and list properties).
  • Transaction support:

    • Added TransactionContext flags for begin, commit, and rollback to coordinate transactional operations across requests.
    • Enhanced type conversion utilities for safe proto ↔︎ Java object mapping, including embedded documents and collections.
  • Client-side API:

    • Full client-side implementation in RemoteGrpcDatabase with a simple, extensible API.

Motivation

  • To provide a native, efficient, and type-safe remote API for ArcadeDB that goes beyond REST/HTTP performance and reliability limitations.
  • To support streaming use cases and bulk data ingestion for high-volume workloads.
  • To align ArcadeDB with modern distributed and reactive application architectures where gRPC is the standard for service-to-service communication.
  • To improve developer experience with generated client stubs and auto-completion.

Related issues

N/A


Additional Notes

I don't yet have a set of client-side tests. These will be provided shortly.


Checklist

  • mvn -DskipTests install
  • Create a Docker image with mvn clean package -Pdocker in the package module

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 @oc007us, 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 significantly enhances ArcadeDB's remote access capabilities by integrating gRPC. The primary goal is to move beyond the performance and reliability limitations of traditional REST/HTTP, offering a native, efficient, and type-safe communication layer. This enables high-volume streaming and bulk data ingestion workloads, aligning ArcadeDB with modern distributed and reactive application architectures. The changes aim to improve overall developer experience through generated client stubs and better performance characteristics.

Highlights

  • gRPC Core Integration: Introduces full gRPC support for ArcadeDB, providing a strongly-typed, high-performance API for remote database access.
  • Advanced Query Streaming: Enables streaming query execution with multiple retrieval modes: CURSOR (existing behavior), MATERIALIZE_ALL (materializes all results before batching), and PAGED (reissues queries per batch using LIMIT/SKIP for efficient paging).
  • Flexible Insert Operations: Adds various insert mechanisms including BulkInsert (single request for large batches), InsertStream (client-streaming with server-side batching), and InsertBidirectional (full duplex with per-batch acknowledgements and transaction control).
  • Comprehensive Record & Transaction Handling: Supports create, update, and lookup operations for records with schema-aware property handling, alongside robust transaction support via TransactionContext flags for begin, commit, and rollback, and enhanced type conversion utilities.
  • Dedicated Client and Server Components: Includes a full client-side implementation in RemoteGrpcDatabase and server-side components (ArcadeDbGrpcService, GrpcServerPlugin) with interceptors for logging, metrics, authentication, and compression.
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 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. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

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 configure Gemini 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 comprehensive gRPC support for ArcadeDB, which is a significant and valuable addition. The implementation covers unary, streaming, and bulk operations, along with a new gRPC client. My review focuses on ensuring the new code is robust, maintainable, and consistent. I've identified several areas for improvement, including the removal of redundant code and a duplicate Protobuf definition, more consistent exception handling, and making data conversions more robust. Addressing these points will help solidify this new API as a first-class citizen in the ArcadeDB ecosystem.

@@ -0,0 +1,281 @@
syntax = "proto3";
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

This Protobuf file appears to be a duplicate and outdated version of the one located at grpc/src/main/proto/arcadedb-server.proto. Maintaining multiple versions of the API definition can lead to inconsistencies and build issues. This file should be removed to ensure there is a single source of truth for the gRPC service contract.

Comment on lines 1500 to 1520
private com.google.protobuf.Value toProtoValue(Object v) {
com.google.protobuf.Value.Builder vb = com.google.protobuf.Value.newBuilder();
if (v == null) return vb.setNullValue(com.google.protobuf.NullValue.NULL_VALUE).build();
if (v instanceof String s) return vb.setStringValue(s).build();
if (v instanceof Boolean b) return vb.setBoolValue(b).build();
if (v instanceof Number n) return vb.setNumberValue(n.doubleValue()).build();
if (v instanceof java.time.Instant t)
return vb.setStringValue(t.toString()).build(); // or a Struct for Timestamp if you prefer
if (v instanceof java.util.Map<?,?> m) {
var sb = com.google.protobuf.Struct.newBuilder();
for (var e : m.entrySet())
sb.putFields(String.valueOf(e.getKey()), toProtoValue(e.getValue()));
return vb.setStructValue(sb.build()).build();
}
if (v instanceof java.util.List<?> list) {
var lb = com.google.protobuf.ListValue.newBuilder();
for (Object e : list) lb.addValues(toProtoValue(e));
return vb.setListValue(lb.build()).build();
}
return vb.setStringValue(String.valueOf(v)).build();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The toProtoValue method converts unknown object types to a string using toString(). This can lead to silent data loss or incorrect data representation for complex types that are not explicitly handled (e.g., byte arrays, custom date/time types, etc.). Consider making this conversion more robust by either throwing an IllegalArgumentException for unsupported types or by adding explicit handling for more common types like byte[].

Comment on lines 1775 to 1792
public static class RemoteGrpcDatabaseWithCompression extends RemoteGrpcDatabase {

public RemoteGrpcDatabaseWithCompression(String server, int port, String databaseName, String userName, String userPassword,
ContextConfiguration configuration) {
super(server, port, databaseName, userName, userPassword, configuration);
}

@Override
protected ManagedChannel createChannel(String server, int port) {

return ManagedChannelBuilder.forAddress(server, port).usePlaintext() // No TLS/SSL
.compressorRegistry(CompressorRegistry.getDefaultInstance())
.decompressorRegistry(DecompressorRegistry.getDefaultInstance())
.maxInboundMessageSize(100 * 1024 * 1024) // 100MB max message size
.keepAliveTime(30, TimeUnit.SECONDS) // Keep-alive configuration
.keepAliveTimeout(10, TimeUnit.SECONDS).keepAliveWithoutCalls(true).build();
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

This inner class RemoteGrpcDatabaseWithCompression seems redundant, as there is a separate top-level class grpc-client/src/main/java/com/arcadedb/remote/grpc/RemoteGrpcDatabaseWithCompression.java that serves the same purpose. The implementation here is also different from the top-level class, which can cause confusion. This inner class should likely be removed to avoid duplication and maintain a single source of truth for this functionality.

Comment on lines +1549 to +1562
private TransactionIsolation mapIsolationLevel(Database.TRANSACTION_ISOLATION_LEVEL level) {
switch (level) {
// case READ_UNCOMMITTED:
// return TransactionIsolation.READ_UNCOMMITTED;
case READ_COMMITTED:
return TransactionIsolation.READ_COMMITTED;
case REPEATABLE_READ:
return TransactionIsolation.REPEATABLE_READ;
// case SERIALIZABLE:
// return TransactionIsolation.SERIALIZABLE;
default:
return TransactionIsolation.READ_COMMITTED;
}
}
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 mapIsolationLevel method is missing cases for READ_UNCOMMITTED and SERIALIZABLE isolation levels, which are commented out. If these levels are intentionally unsupported over gRPC, it would be clearer to throw an UnsupportedOperationException or add a comment explaining why they are omitted. Otherwise, they should be implemented.

@@ -0,0 +1,422 @@
# ArcadeDB gRPC Server Configuration Examples
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This file appears to be a collection of notes and examples for gRPC configuration and usage. For better readability and maintainability, consider the following improvements:

  • Rename to README.md: This will enable Markdown rendering, making the headers, code blocks, and lists much easier to read.
  • Structure and Consolidate: The content has several repeated sections (e.g., Docker commands, configuration properties). Consolidating these into clearly defined sections would make the document more useful as a reference.

@robfrank robfrank self-assigned this Sep 2, 2025
@robfrank robfrank added the enhancement New feature or request label Sep 2, 2025
@robfrank robfrank added this to the 25.9.1 milestone Sep 2, 2025
This was referenced Sep 11, 2025
@robfrank
Copy link
Collaborator

Duplicated to #2499 and merged
Thanks @oc007us !

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.

4 participants