feat: replace gRPC transport with FIBP binary protocol - #5

Merged
vieiralucas merged 3 commits into
mainfrom
feat/fibp-transport
Mar 26, 2026
Merged

feat: replace gRPC transport with FIBP binary protocol#5
vieiralucas merged 3 commits into
mainfrom
feat/fibp-transport

Conversation

@vieiralucas

@vieiralucasvieiralucas commented Mar 26, 2026

Copy link
Copy Markdown
Member

Summary

  • Replaces the gRPC/protobuf transport with FIBP (Fila Binary Protocol) over raw TCP/TLS
  • Removes all gRPC and protobuf dependencies from build.gradle (no runtime dependencies remain)
  • Adds FibpConnection — TCP socket with length-prefixed framing, handshake, correlation-ID multiplexing via ConcurrentHashMap + CompletableFuture, heartbeat scheduler, and optional TLS via SSLSocket
  • Adds FibpCodec — wire encoding/decoding matching fila-core/src/fibp/wire.rs exactly (enqueue, consume push batch, ack, nack, error frames)
  • Keeps the public FilaClient API identical: enqueue, enqueueMany, consume, ack, nack, close, Builder with all TLS/auth/batch options preserved
  • Batcher groups messages by queue before sending (one FIBP enqueue frame per queue name, since the frame-level field is per-queue)
  • RpcException.Code replaces io.grpc.Status.Code; error classification uses keyword matching on plain-text error payloads (matching the Rust SDK pattern)
  • AUTH uses raw key bytes in OP_AUTH frame (no length prefix, matching server protocol)
  • Consume push frames decoded as batches (msg_count:u16 | messages...)
  • FibpAdminClient added to test package with hand-rolled minimal protobuf for CreateQueueRequest (avoids a test protobuf dependency)
  • Integration tests (FilaClientTest, BatchClientTest, TlsAuthClientTest) guarded by @EnabledIf("serverAvailable") and skip cleanly when no binary is present; unit tests all pass

Test plan

  • All 21 unit tests pass (./gradlew test)
  • spotlessCheck passes (formatting enforced by Google Java Format)
  • CI integration tests pass against downloaded fila-server binary
  • TLS tests: verify withTls(), withTlsCaCert(), withTlsClientCert() (mTLS) all connect
  • Auth tests: verify withApiKey() sends AUTH frame and server accepts/rejects correctly

🤖 Generated with Claude Code


Summary by cubic

Replaced the gRPC/protobuf transport with FIBP (Fila Binary Protocol) over raw TCP/TLS while keeping the public FilaClient API the same. This removes all gRPC/protobuf deps, adds a single-socket multiplexed connection with heartbeat and AUTH, and includes stability/validation fixes.

  • New Features

    • Added FibpConnection: framing, handshake, correlation IDs, heartbeat scheduler, optional TLS, and AUTH via OP_AUTH.
    • Added FibpCodec: encode/decode for enqueue, batched consume push, ack/nack, and error frames; validates header count (<=255) and str16 length (<=65535).
    • Public FilaClient API unchanged; batcher groups messages by queue and sends one enqueue frame per queue; enqueueMany enforces a single target queue.
    • Replaced gRPC status with RpcException.Code; errors mapped from server error text.
    • Robustness: remove pending futures on consume timeout/interrupt; guard push handler exceptions to keep the reader thread alive; map batch timeouts to UNAVAILABLE; add a fallback catch in the batcher to resolve futures with INTERNAL on unexpected exceptions.
    • Tests use FibpAdminClient for queue creation (supports TLS/mTLS); README updated; version bumped to 0.3.0.
  • Migration

    • Update dependency to dev.faisca:fila-client:0.3.0.
    • Replace any uses of gRPC Status.Code with RpcException.Code.
    • build() now opens a connection; tests that constructed clients without a running server should guard or defer client creation.
    • Consume handlers run on the FIBP reader thread; avoid heavy or blocking work in the callback.
    • enqueueMany should target a single queue per call.

Written for commit 03bf792. Summary will update on new commits.

rewrite the java sdk transport layer to use fibp (fila binary protocol)
over raw tcp instead of grpc/protobuf.
- add FibpConnection: tcp socket with length-prefixed framing, handshake,
correlation-id multiplexing via ConcurrentHashMap + CompletableFuture,
heartbeat scheduler, and optional tls via SSLSocket
- add FibpCodec: wire encoding/decoding for enqueue, consume push batch,
ack, nack, and error frames (exact format from fila-core/src/fibp/wire.rs)
- rewrite FilaClient to use FibpConnection; remove all grpc/protobuf deps
- rewrite Batcher to use FibpConnection; groups messages by queue into
separate fibp frames (one queue name per enqueue frame)
- rewrite ConsumerHandle without grpc Context dependency
- update RpcException to define its own Code enum (no grpc Status.Code)
- remove ApiKeyInterceptor (auth now via fibp OP_AUTH frame)
- remove proto/ directory and grpc/protobuf gradle deps; bump to v0.3.0
- add FibpAdminClient in test package for createQueue (hand-rolled protobuf
encoding of CreateQueueRequest, avoids adding a test protobuf dependency)
- update TestServer to use FibpAdminClient instead of grpc admin stub
- update BuilderTest: remove tests that require a server connection (fibp
connects eagerly unlike grpc lazy channels); add address-parsing unit tests
- add @EnabledIf("serverAvailable") guard to FilaClientTest
- update TlsAuthClientTest to use RpcException.Code instead of grpc Status.Code

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

7 issues found across 17 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/main/java/dev/faisca/fila/FibpConnection.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FibpConnection.java:191">
P2: Remove the pending entry when the consume setup times out or is interrupted; otherwise the failed consume leaves a stale future in the pending map.</violation>
<violation number="2" location="src/main/java/dev/faisca/fila/FibpConnection.java:328">
P2: Guard push handlers so an exception doesn’t kill the reader thread and strand pending requests.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/FibpCodec.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FibpCodec.java:73">
P2: Guard the header count before writing the u8 field. Counts >255 wrap in writeByte and desynchronize the frame.</violation>
<violation number="2" location="src/main/java/dev/faisca/fila/FibpCodec.java:311">
P2: Validate str16 lengths before writing. Without a bounds check, strings longer than 65,535 bytes wrap in writeShort and corrupt the frame.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/FilaClient.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FilaClient.java:112">
P2: enqueueMany does not enforce that all messages target the same queue even though the FIBP frame encodes only the first queue name. Mixed-queue batches will silently send messages to the wrong queue.</violation>
</file>
<file name="src/test/java/dev/faisca/fila/TestServer.java">
<violation number="1" location="src/test/java/dev/faisca/fila/TestServer.java:88">
P2: createQueueWithApiKey now connects over a plain Socket via FibpAdminClient, but it is used immediately after startWithTls. This skips TLS/mTLS setup, so queue creation will fail against a TLS-enabled server.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/Batcher.java">
<violation number="1" location="src/main/java/dev/faisca/fila/Batcher.java:239">
P2: respFuture.get can throw InterruptedException/TimeoutException, but the generic catch maps them to INTERNAL and clears the interrupt. Handle these explicitly (restore interrupt + map timeout to UNAVAILABLE) so batched enqueue errors match sendSync behavior.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment threadsrc/main/java/dev/faisca/fila/FibpConnection.java
Comment threadsrc/main/java/dev/faisca/fila/FibpConnection.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/FibpCodec.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/FibpCodec.java
Comment threadsrc/main/java/dev/faisca/fila/FilaClient.java
Comment threadsrc/test/java/dev/faisca/fila/TestServer.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/Batcher.java
- FibpConnection: remove pending entry on consume timeout/interrupt to
prevent stale future accumulation in the pending map
- FibpConnection: guard push handler invocations so exceptions from the
user handler do not kill the reader thread and strand pending requests
- FibpCodec: validate header count <= 255 before writing u8 field
- FibpCodec: validate str16 string length <= 65535 before writing u16
- FilaClient.enqueueMany: validate all messages target the same queue —
FIBP enqueue frames encode one queue name at the request level
- Batcher.flushQueueBatch: handle InterruptedException and TimeoutException
explicitly; restore interrupt flag and map timeout to UNAVAILABLE
- FibpAdminClient: add TLS/mTLS support so createQueueWithApiKey works
against TLS-enabled servers
- TestServer.createQueueImpl: use TLS connection when server has TLS enabled

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 6 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/main/java/dev/faisca/fila/Batcher.java">
<violation number="1" location="src/main/java/dev/faisca/fila/Batcher.java:244">
P2: The generic catch-all was removed, so unexpected runtime exceptions (e.g., decodeEnqueueResponse failures) will now escape this method and leave the per-item futures unresolved. Add a fallback catch to map and complete all futures on any other exception.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment threadsrc/main/java/dev/faisca/fila/Batcher.java
without the fallback, unexpected runtime exceptions such as those from
decodeEnqueueResponse can escape flushQueueBatch and leave per-item
CompletableFuture instances unresolved, blocking callers indefinitely.
add a RuntimeException catch-all after the typed handlers that resolves
all futures with an INTERNAL error.
@vieiralucas
vieiralucas merged commit 6694a8e into mainMar 26, 2026
2 checks passed
Sign up for freeto 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.

1 participant

@vieiralucas
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: replace gRPC transport with FIBP binary protocol - #5

Merged
vieiralucas merged 3 commits into
mainfrom
feat/fibp-transport
Mar 26, 2026
Merged

feat: replace gRPC transport with FIBP binary protocol#5
vieiralucas merged 3 commits into
mainfrom
feat/fibp-transport

Conversation

@vieiralucas

@vieiralucasvieiralucas commented Mar 26, 2026

Copy link
Copy Markdown
Member

Summary

  • Replaces the gRPC/protobuf transport with FIBP (Fila Binary Protocol) over raw TCP/TLS
  • Removes all gRPC and protobuf dependencies from build.gradle (no runtime dependencies remain)
  • Adds FibpConnection — TCP socket with length-prefixed framing, handshake, correlation-ID multiplexing via ConcurrentHashMap + CompletableFuture, heartbeat scheduler, and optional TLS via SSLSocket
  • Adds FibpCodec — wire encoding/decoding matching fila-core/src/fibp/wire.rs exactly (enqueue, consume push batch, ack, nack, error frames)
  • Keeps the public FilaClient API identical: enqueue, enqueueMany, consume, ack, nack, close, Builder with all TLS/auth/batch options preserved
  • Batcher groups messages by queue before sending (one FIBP enqueue frame per queue name, since the frame-level field is per-queue)
  • RpcException.Code replaces io.grpc.Status.Code; error classification uses keyword matching on plain-text error payloads (matching the Rust SDK pattern)
  • AUTH uses raw key bytes in OP_AUTH frame (no length prefix, matching server protocol)
  • Consume push frames decoded as batches (msg_count:u16 | messages...)
  • FibpAdminClient added to test package with hand-rolled minimal protobuf for CreateQueueRequest (avoids a test protobuf dependency)
  • Integration tests (FilaClientTest, BatchClientTest, TlsAuthClientTest) guarded by @EnabledIf("serverAvailable") and skip cleanly when no binary is present; unit tests all pass

Test plan

  • All 21 unit tests pass (./gradlew test)
  • spotlessCheck passes (formatting enforced by Google Java Format)
  • CI integration tests pass against downloaded fila-server binary
  • TLS tests: verify withTls(), withTlsCaCert(), withTlsClientCert() (mTLS) all connect
  • Auth tests: verify withApiKey() sends AUTH frame and server accepts/rejects correctly

🤖 Generated with Claude Code


Summary by cubic

Replaced the gRPC/protobuf transport with FIBP (Fila Binary Protocol) over raw TCP/TLS while keeping the public FilaClient API the same. This removes all gRPC/protobuf deps, adds a single-socket multiplexed connection with heartbeat and AUTH, and includes stability/validation fixes.

  • New Features

    • Added FibpConnection: framing, handshake, correlation IDs, heartbeat scheduler, optional TLS, and AUTH via OP_AUTH.
    • Added FibpCodec: encode/decode for enqueue, batched consume push, ack/nack, and error frames; validates header count (<=255) and str16 length (<=65535).
    • Public FilaClient API unchanged; batcher groups messages by queue and sends one enqueue frame per queue; enqueueMany enforces a single target queue.
    • Replaced gRPC status with RpcException.Code; errors mapped from server error text.
    • Robustness: remove pending futures on consume timeout/interrupt; guard push handler exceptions to keep the reader thread alive; map batch timeouts to UNAVAILABLE; add a fallback catch in the batcher to resolve futures with INTERNAL on unexpected exceptions.
    • Tests use FibpAdminClient for queue creation (supports TLS/mTLS); README updated; version bumped to 0.3.0.
  • Migration

    • Update dependency to dev.faisca:fila-client:0.3.0.
    • Replace any uses of gRPC Status.Code with RpcException.Code.
    • build() now opens a connection; tests that constructed clients without a running server should guard or defer client creation.
    • Consume handlers run on the FIBP reader thread; avoid heavy or blocking work in the callback.
    • enqueueMany should target a single queue per call.

Written for commit 03bf792. Summary will update on new commits.

rewrite the java sdk transport layer to use fibp (fila binary protocol)
over raw tcp instead of grpc/protobuf.
- add FibpConnection: tcp socket with length-prefixed framing, handshake,
correlation-id multiplexing via ConcurrentHashMap + CompletableFuture,
heartbeat scheduler, and optional tls via SSLSocket
- add FibpCodec: wire encoding/decoding for enqueue, consume push batch,
ack, nack, and error frames (exact format from fila-core/src/fibp/wire.rs)
- rewrite FilaClient to use FibpConnection; remove all grpc/protobuf deps
- rewrite Batcher to use FibpConnection; groups messages by queue into
separate fibp frames (one queue name per enqueue frame)
- rewrite ConsumerHandle without grpc Context dependency
- update RpcException to define its own Code enum (no grpc Status.Code)
- remove ApiKeyInterceptor (auth now via fibp OP_AUTH frame)
- remove proto/ directory and grpc/protobuf gradle deps; bump to v0.3.0
- add FibpAdminClient in test package for createQueue (hand-rolled protobuf
encoding of CreateQueueRequest, avoids adding a test protobuf dependency)
- update TestServer to use FibpAdminClient instead of grpc admin stub
- update BuilderTest: remove tests that require a server connection (fibp
connects eagerly unlike grpc lazy channels); add address-parsing unit tests
- add @EnabledIf("serverAvailable") guard to FilaClientTest
- update TlsAuthClientTest to use RpcException.Code instead of grpc Status.Code

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

7 issues found across 17 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/main/java/dev/faisca/fila/FibpConnection.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FibpConnection.java:191">
P2: Remove the pending entry when the consume setup times out or is interrupted; otherwise the failed consume leaves a stale future in the pending map.</violation>
<violation number="2" location="src/main/java/dev/faisca/fila/FibpConnection.java:328">
P2: Guard push handlers so an exception doesn’t kill the reader thread and strand pending requests.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/FibpCodec.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FibpCodec.java:73">
P2: Guard the header count before writing the u8 field. Counts >255 wrap in writeByte and desynchronize the frame.</violation>
<violation number="2" location="src/main/java/dev/faisca/fila/FibpCodec.java:311">
P2: Validate str16 lengths before writing. Without a bounds check, strings longer than 65,535 bytes wrap in writeShort and corrupt the frame.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/FilaClient.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FilaClient.java:112">
P2: enqueueMany does not enforce that all messages target the same queue even though the FIBP frame encodes only the first queue name. Mixed-queue batches will silently send messages to the wrong queue.</violation>
</file>
<file name="src/test/java/dev/faisca/fila/TestServer.java">
<violation number="1" location="src/test/java/dev/faisca/fila/TestServer.java:88">
P2: createQueueWithApiKey now connects over a plain Socket via FibpAdminClient, but it is used immediately after startWithTls. This skips TLS/mTLS setup, so queue creation will fail against a TLS-enabled server.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/Batcher.java">
<violation number="1" location="src/main/java/dev/faisca/fila/Batcher.java:239">
P2: respFuture.get can throw InterruptedException/TimeoutException, but the generic catch maps them to INTERNAL and clears the interrupt. Handle these explicitly (restore interrupt + map timeout to UNAVAILABLE) so batched enqueue errors match sendSync behavior.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment threadsrc/main/java/dev/faisca/fila/FibpConnection.java
Comment threadsrc/main/java/dev/faisca/fila/FibpConnection.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/FibpCodec.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/FibpCodec.java
Comment threadsrc/main/java/dev/faisca/fila/FilaClient.java
Comment threadsrc/test/java/dev/faisca/fila/TestServer.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/Batcher.java
- FibpConnection: remove pending entry on consume timeout/interrupt to
prevent stale future accumulation in the pending map
- FibpConnection: guard push handler invocations so exceptions from the
user handler do not kill the reader thread and strand pending requests
- FibpCodec: validate header count <= 255 before writing u8 field
- FibpCodec: validate str16 string length <= 65535 before writing u16
- FilaClient.enqueueMany: validate all messages target the same queue —
FIBP enqueue frames encode one queue name at the request level
- Batcher.flushQueueBatch: handle InterruptedException and TimeoutException
explicitly; restore interrupt flag and map timeout to UNAVAILABLE
- FibpAdminClient: add TLS/mTLS support so createQueueWithApiKey works
against TLS-enabled servers
- TestServer.createQueueImpl: use TLS connection when server has TLS enabled

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 6 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/main/java/dev/faisca/fila/Batcher.java">
<violation number="1" location="src/main/java/dev/faisca/fila/Batcher.java:244">
P2: The generic catch-all was removed, so unexpected runtime exceptions (e.g., decodeEnqueueResponse failures) will now escape this method and leave the per-item futures unresolved. Add a fallback catch to map and complete all futures on any other exception.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment threadsrc/main/java/dev/faisca/fila/Batcher.java
without the fallback, unexpected runtime exceptions such as those from
decodeEnqueueResponse can escape flushQueueBatch and leave per-item
CompletableFuture instances unresolved, blocking callers indefinitely.
add a RuntimeException catch-all after the typed handlers that resolves
all futures with an INTERNAL error.
@vieiralucas
vieiralucas merged commit 6694a8e into mainMar 26, 2026
2 checks passed
Sign up for freeto 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.

1 participant

@vieiralucas
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: replace gRPC transport with FIBP binary protocol - #5

Merged
vieiralucas merged 3 commits into
mainfrom
feat/fibp-transport
Mar 26, 2026
Merged

feat: replace gRPC transport with FIBP binary protocol#5
vieiralucas merged 3 commits into
mainfrom
feat/fibp-transport

Conversation

@vieiralucas

@vieiralucasvieiralucas commented Mar 26, 2026

Copy link
Copy Markdown
Member

Summary

  • Replaces the gRPC/protobuf transport with FIBP (Fila Binary Protocol) over raw TCP/TLS
  • Removes all gRPC and protobuf dependencies from build.gradle (no runtime dependencies remain)
  • Adds FibpConnection — TCP socket with length-prefixed framing, handshake, correlation-ID multiplexing via ConcurrentHashMap + CompletableFuture, heartbeat scheduler, and optional TLS via SSLSocket
  • Adds FibpCodec — wire encoding/decoding matching fila-core/src/fibp/wire.rs exactly (enqueue, consume push batch, ack, nack, error frames)
  • Keeps the public FilaClient API identical: enqueue, enqueueMany, consume, ack, nack, close, Builder with all TLS/auth/batch options preserved
  • Batcher groups messages by queue before sending (one FIBP enqueue frame per queue name, since the frame-level field is per-queue)
  • RpcException.Code replaces io.grpc.Status.Code; error classification uses keyword matching on plain-text error payloads (matching the Rust SDK pattern)
  • AUTH uses raw key bytes in OP_AUTH frame (no length prefix, matching server protocol)
  • Consume push frames decoded as batches (msg_count:u16 | messages...)
  • FibpAdminClient added to test package with hand-rolled minimal protobuf for CreateQueueRequest (avoids a test protobuf dependency)
  • Integration tests (FilaClientTest, BatchClientTest, TlsAuthClientTest) guarded by @EnabledIf("serverAvailable") and skip cleanly when no binary is present; unit tests all pass

Test plan

  • All 21 unit tests pass (./gradlew test)
  • spotlessCheck passes (formatting enforced by Google Java Format)
  • CI integration tests pass against downloaded fila-server binary
  • TLS tests: verify withTls(), withTlsCaCert(), withTlsClientCert() (mTLS) all connect
  • Auth tests: verify withApiKey() sends AUTH frame and server accepts/rejects correctly

🤖 Generated with Claude Code


Summary by cubic

Replaced the gRPC/protobuf transport with FIBP (Fila Binary Protocol) over raw TCP/TLS while keeping the public FilaClient API the same. This removes all gRPC/protobuf deps, adds a single-socket multiplexed connection with heartbeat and AUTH, and includes stability/validation fixes.

  • New Features

    • Added FibpConnection: framing, handshake, correlation IDs, heartbeat scheduler, optional TLS, and AUTH via OP_AUTH.
    • Added FibpCodec: encode/decode for enqueue, batched consume push, ack/nack, and error frames; validates header count (<=255) and str16 length (<=65535).
    • Public FilaClient API unchanged; batcher groups messages by queue and sends one enqueue frame per queue; enqueueMany enforces a single target queue.
    • Replaced gRPC status with RpcException.Code; errors mapped from server error text.
    • Robustness: remove pending futures on consume timeout/interrupt; guard push handler exceptions to keep the reader thread alive; map batch timeouts to UNAVAILABLE; add a fallback catch in the batcher to resolve futures with INTERNAL on unexpected exceptions.
    • Tests use FibpAdminClient for queue creation (supports TLS/mTLS); README updated; version bumped to 0.3.0.
  • Migration

    • Update dependency to dev.faisca:fila-client:0.3.0.
    • Replace any uses of gRPC Status.Code with RpcException.Code.
    • build() now opens a connection; tests that constructed clients without a running server should guard or defer client creation.
    • Consume handlers run on the FIBP reader thread; avoid heavy or blocking work in the callback.
    • enqueueMany should target a single queue per call.

Written for commit 03bf792. Summary will update on new commits.

rewrite the java sdk transport layer to use fibp (fila binary protocol)
over raw tcp instead of grpc/protobuf.
- add FibpConnection: tcp socket with length-prefixed framing, handshake,
correlation-id multiplexing via ConcurrentHashMap + CompletableFuture,
heartbeat scheduler, and optional tls via SSLSocket
- add FibpCodec: wire encoding/decoding for enqueue, consume push batch,
ack, nack, and error frames (exact format from fila-core/src/fibp/wire.rs)
- rewrite FilaClient to use FibpConnection; remove all grpc/protobuf deps
- rewrite Batcher to use FibpConnection; groups messages by queue into
separate fibp frames (one queue name per enqueue frame)
- rewrite ConsumerHandle without grpc Context dependency
- update RpcException to define its own Code enum (no grpc Status.Code)
- remove ApiKeyInterceptor (auth now via fibp OP_AUTH frame)
- remove proto/ directory and grpc/protobuf gradle deps; bump to v0.3.0
- add FibpAdminClient in test package for createQueue (hand-rolled protobuf
encoding of CreateQueueRequest, avoids adding a test protobuf dependency)
- update TestServer to use FibpAdminClient instead of grpc admin stub
- update BuilderTest: remove tests that require a server connection (fibp
connects eagerly unlike grpc lazy channels); add address-parsing unit tests
- add @EnabledIf("serverAvailable") guard to FilaClientTest
- update TlsAuthClientTest to use RpcException.Code instead of grpc Status.Code

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

7 issues found across 17 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/main/java/dev/faisca/fila/FibpConnection.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FibpConnection.java:191">
P2: Remove the pending entry when the consume setup times out or is interrupted; otherwise the failed consume leaves a stale future in the pending map.</violation>
<violation number="2" location="src/main/java/dev/faisca/fila/FibpConnection.java:328">
P2: Guard push handlers so an exception doesn’t kill the reader thread and strand pending requests.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/FibpCodec.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FibpCodec.java:73">
P2: Guard the header count before writing the u8 field. Counts >255 wrap in writeByte and desynchronize the frame.</violation>
<violation number="2" location="src/main/java/dev/faisca/fila/FibpCodec.java:311">
P2: Validate str16 lengths before writing. Without a bounds check, strings longer than 65,535 bytes wrap in writeShort and corrupt the frame.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/FilaClient.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FilaClient.java:112">
P2: enqueueMany does not enforce that all messages target the same queue even though the FIBP frame encodes only the first queue name. Mixed-queue batches will silently send messages to the wrong queue.</violation>
</file>
<file name="src/test/java/dev/faisca/fila/TestServer.java">
<violation number="1" location="src/test/java/dev/faisca/fila/TestServer.java:88">
P2: createQueueWithApiKey now connects over a plain Socket via FibpAdminClient, but it is used immediately after startWithTls. This skips TLS/mTLS setup, so queue creation will fail against a TLS-enabled server.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/Batcher.java">
<violation number="1" location="src/main/java/dev/faisca/fila/Batcher.java:239">
P2: respFuture.get can throw InterruptedException/TimeoutException, but the generic catch maps them to INTERNAL and clears the interrupt. Handle these explicitly (restore interrupt + map timeout to UNAVAILABLE) so batched enqueue errors match sendSync behavior.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment threadsrc/main/java/dev/faisca/fila/FibpConnection.java
Comment threadsrc/main/java/dev/faisca/fila/FibpConnection.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/FibpCodec.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/FibpCodec.java
Comment threadsrc/main/java/dev/faisca/fila/FilaClient.java
Comment threadsrc/test/java/dev/faisca/fila/TestServer.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/Batcher.java
- FibpConnection: remove pending entry on consume timeout/interrupt to
prevent stale future accumulation in the pending map
- FibpConnection: guard push handler invocations so exceptions from the
user handler do not kill the reader thread and strand pending requests
- FibpCodec: validate header count <= 255 before writing u8 field
- FibpCodec: validate str16 string length <= 65535 before writing u16
- FilaClient.enqueueMany: validate all messages target the same queue —
FIBP enqueue frames encode one queue name at the request level
- Batcher.flushQueueBatch: handle InterruptedException and TimeoutException
explicitly; restore interrupt flag and map timeout to UNAVAILABLE
- FibpAdminClient: add TLS/mTLS support so createQueueWithApiKey works
against TLS-enabled servers
- TestServer.createQueueImpl: use TLS connection when server has TLS enabled

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 6 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/main/java/dev/faisca/fila/Batcher.java">
<violation number="1" location="src/main/java/dev/faisca/fila/Batcher.java:244">
P2: The generic catch-all was removed, so unexpected runtime exceptions (e.g., decodeEnqueueResponse failures) will now escape this method and leave the per-item futures unresolved. Add a fallback catch to map and complete all futures on any other exception.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment threadsrc/main/java/dev/faisca/fila/Batcher.java
without the fallback, unexpected runtime exceptions such as those from
decodeEnqueueResponse can escape flushQueueBatch and leave per-item
CompletableFuture instances unresolved, blocking callers indefinitely.
add a RuntimeException catch-all after the typed handlers that resolves
all futures with an INTERNAL error.
@vieiralucas
vieiralucas merged commit 6694a8e into mainMar 26, 2026
2 checks passed
Sign up for freeto 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.

1 participant

@vieiralucas
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: replace gRPC transport with FIBP binary protocol - #5

Merged
vieiralucas merged 3 commits into
mainfrom
feat/fibp-transport
Mar 26, 2026
Merged

feat: replace gRPC transport with FIBP binary protocol#5
vieiralucas merged 3 commits into
mainfrom
feat/fibp-transport

Conversation

@vieiralucas

@vieiralucasvieiralucas commented Mar 26, 2026

Copy link
Copy Markdown
Member

Summary

  • Replaces the gRPC/protobuf transport with FIBP (Fila Binary Protocol) over raw TCP/TLS
  • Removes all gRPC and protobuf dependencies from build.gradle (no runtime dependencies remain)
  • Adds FibpConnection — TCP socket with length-prefixed framing, handshake, correlation-ID multiplexing via ConcurrentHashMap + CompletableFuture, heartbeat scheduler, and optional TLS via SSLSocket
  • Adds FibpCodec — wire encoding/decoding matching fila-core/src/fibp/wire.rs exactly (enqueue, consume push batch, ack, nack, error frames)
  • Keeps the public FilaClient API identical: enqueue, enqueueMany, consume, ack, nack, close, Builder with all TLS/auth/batch options preserved
  • Batcher groups messages by queue before sending (one FIBP enqueue frame per queue name, since the frame-level field is per-queue)
  • RpcException.Code replaces io.grpc.Status.Code; error classification uses keyword matching on plain-text error payloads (matching the Rust SDK pattern)
  • AUTH uses raw key bytes in OP_AUTH frame (no length prefix, matching server protocol)
  • Consume push frames decoded as batches (msg_count:u16 | messages...)
  • FibpAdminClient added to test package with hand-rolled minimal protobuf for CreateQueueRequest (avoids a test protobuf dependency)
  • Integration tests (FilaClientTest, BatchClientTest, TlsAuthClientTest) guarded by @EnabledIf("serverAvailable") and skip cleanly when no binary is present; unit tests all pass

Test plan

  • All 21 unit tests pass (./gradlew test)
  • spotlessCheck passes (formatting enforced by Google Java Format)
  • CI integration tests pass against downloaded fila-server binary
  • TLS tests: verify withTls(), withTlsCaCert(), withTlsClientCert() (mTLS) all connect
  • Auth tests: verify withApiKey() sends AUTH frame and server accepts/rejects correctly

🤖 Generated with Claude Code


Summary by cubic

Replaced the gRPC/protobuf transport with FIBP (Fila Binary Protocol) over raw TCP/TLS while keeping the public FilaClient API the same. This removes all gRPC/protobuf deps, adds a single-socket multiplexed connection with heartbeat and AUTH, and includes stability/validation fixes.

  • New Features

    • Added FibpConnection: framing, handshake, correlation IDs, heartbeat scheduler, optional TLS, and AUTH via OP_AUTH.
    • Added FibpCodec: encode/decode for enqueue, batched consume push, ack/nack, and error frames; validates header count (<=255) and str16 length (<=65535).
    • Public FilaClient API unchanged; batcher groups messages by queue and sends one enqueue frame per queue; enqueueMany enforces a single target queue.
    • Replaced gRPC status with RpcException.Code; errors mapped from server error text.
    • Robustness: remove pending futures on consume timeout/interrupt; guard push handler exceptions to keep the reader thread alive; map batch timeouts to UNAVAILABLE; add a fallback catch in the batcher to resolve futures with INTERNAL on unexpected exceptions.
    • Tests use FibpAdminClient for queue creation (supports TLS/mTLS); README updated; version bumped to 0.3.0.
  • Migration

    • Update dependency to dev.faisca:fila-client:0.3.0.
    • Replace any uses of gRPC Status.Code with RpcException.Code.
    • build() now opens a connection; tests that constructed clients without a running server should guard or defer client creation.
    • Consume handlers run on the FIBP reader thread; avoid heavy or blocking work in the callback.
    • enqueueMany should target a single queue per call.

Written for commit 03bf792. Summary will update on new commits.

rewrite the java sdk transport layer to use fibp (fila binary protocol)
over raw tcp instead of grpc/protobuf.
- add FibpConnection: tcp socket with length-prefixed framing, handshake,
correlation-id multiplexing via ConcurrentHashMap + CompletableFuture,
heartbeat scheduler, and optional tls via SSLSocket
- add FibpCodec: wire encoding/decoding for enqueue, consume push batch,
ack, nack, and error frames (exact format from fila-core/src/fibp/wire.rs)
- rewrite FilaClient to use FibpConnection; remove all grpc/protobuf deps
- rewrite Batcher to use FibpConnection; groups messages by queue into
separate fibp frames (one queue name per enqueue frame)
- rewrite ConsumerHandle without grpc Context dependency
- update RpcException to define its own Code enum (no grpc Status.Code)
- remove ApiKeyInterceptor (auth now via fibp OP_AUTH frame)
- remove proto/ directory and grpc/protobuf gradle deps; bump to v0.3.0
- add FibpAdminClient in test package for createQueue (hand-rolled protobuf
encoding of CreateQueueRequest, avoids adding a test protobuf dependency)
- update TestServer to use FibpAdminClient instead of grpc admin stub
- update BuilderTest: remove tests that require a server connection (fibp
connects eagerly unlike grpc lazy channels); add address-parsing unit tests
- add @EnabledIf("serverAvailable") guard to FilaClientTest
- update TlsAuthClientTest to use RpcException.Code instead of grpc Status.Code

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

7 issues found across 17 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/main/java/dev/faisca/fila/FibpConnection.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FibpConnection.java:191">
P2: Remove the pending entry when the consume setup times out or is interrupted; otherwise the failed consume leaves a stale future in the pending map.</violation>
<violation number="2" location="src/main/java/dev/faisca/fila/FibpConnection.java:328">
P2: Guard push handlers so an exception doesn’t kill the reader thread and strand pending requests.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/FibpCodec.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FibpCodec.java:73">
P2: Guard the header count before writing the u8 field. Counts >255 wrap in writeByte and desynchronize the frame.</violation>
<violation number="2" location="src/main/java/dev/faisca/fila/FibpCodec.java:311">
P2: Validate str16 lengths before writing. Without a bounds check, strings longer than 65,535 bytes wrap in writeShort and corrupt the frame.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/FilaClient.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FilaClient.java:112">
P2: enqueueMany does not enforce that all messages target the same queue even though the FIBP frame encodes only the first queue name. Mixed-queue batches will silently send messages to the wrong queue.</violation>
</file>
<file name="src/test/java/dev/faisca/fila/TestServer.java">
<violation number="1" location="src/test/java/dev/faisca/fila/TestServer.java:88">
P2: createQueueWithApiKey now connects over a plain Socket via FibpAdminClient, but it is used immediately after startWithTls. This skips TLS/mTLS setup, so queue creation will fail against a TLS-enabled server.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/Batcher.java">
<violation number="1" location="src/main/java/dev/faisca/fila/Batcher.java:239">
P2: respFuture.get can throw InterruptedException/TimeoutException, but the generic catch maps them to INTERNAL and clears the interrupt. Handle these explicitly (restore interrupt + map timeout to UNAVAILABLE) so batched enqueue errors match sendSync behavior.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment threadsrc/main/java/dev/faisca/fila/FibpConnection.java
Comment threadsrc/main/java/dev/faisca/fila/FibpConnection.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/FibpCodec.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/FibpCodec.java
Comment threadsrc/main/java/dev/faisca/fila/FilaClient.java
Comment threadsrc/test/java/dev/faisca/fila/TestServer.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/Batcher.java
- FibpConnection: remove pending entry on consume timeout/interrupt to
prevent stale future accumulation in the pending map
- FibpConnection: guard push handler invocations so exceptions from the
user handler do not kill the reader thread and strand pending requests
- FibpCodec: validate header count <= 255 before writing u8 field
- FibpCodec: validate str16 string length <= 65535 before writing u16
- FilaClient.enqueueMany: validate all messages target the same queue —
FIBP enqueue frames encode one queue name at the request level
- Batcher.flushQueueBatch: handle InterruptedException and TimeoutException
explicitly; restore interrupt flag and map timeout to UNAVAILABLE
- FibpAdminClient: add TLS/mTLS support so createQueueWithApiKey works
against TLS-enabled servers
- TestServer.createQueueImpl: use TLS connection when server has TLS enabled

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 6 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/main/java/dev/faisca/fila/Batcher.java">
<violation number="1" location="src/main/java/dev/faisca/fila/Batcher.java:244">
P2: The generic catch-all was removed, so unexpected runtime exceptions (e.g., decodeEnqueueResponse failures) will now escape this method and leave the per-item futures unresolved. Add a fallback catch to map and complete all futures on any other exception.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment threadsrc/main/java/dev/faisca/fila/Batcher.java
without the fallback, unexpected runtime exceptions such as those from
decodeEnqueueResponse can escape flushQueueBatch and leave per-item
CompletableFuture instances unresolved, blocking callers indefinitely.
add a RuntimeException catch-all after the typed handlers that resolves
all futures with an INTERNAL error.
@vieiralucas
vieiralucas merged commit 6694a8e into mainMar 26, 2026
2 checks passed
Sign up for freeto 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.

1 participant

@vieiralucas
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: replace gRPC transport with FIBP binary protocol - #5

Merged
vieiralucas merged 3 commits into
mainfrom
feat/fibp-transport
Mar 26, 2026
Merged

feat: replace gRPC transport with FIBP binary protocol#5
vieiralucas merged 3 commits into
mainfrom
feat/fibp-transport

Conversation

@vieiralucas

@vieiralucasvieiralucas commented Mar 26, 2026

Copy link
Copy Markdown
Member

Summary

  • Replaces the gRPC/protobuf transport with FIBP (Fila Binary Protocol) over raw TCP/TLS
  • Removes all gRPC and protobuf dependencies from build.gradle (no runtime dependencies remain)
  • Adds FibpConnection — TCP socket with length-prefixed framing, handshake, correlation-ID multiplexing via ConcurrentHashMap + CompletableFuture, heartbeat scheduler, and optional TLS via SSLSocket
  • Adds FibpCodec — wire encoding/decoding matching fila-core/src/fibp/wire.rs exactly (enqueue, consume push batch, ack, nack, error frames)
  • Keeps the public FilaClient API identical: enqueue, enqueueMany, consume, ack, nack, close, Builder with all TLS/auth/batch options preserved
  • Batcher groups messages by queue before sending (one FIBP enqueue frame per queue name, since the frame-level field is per-queue)
  • RpcException.Code replaces io.grpc.Status.Code; error classification uses keyword matching on plain-text error payloads (matching the Rust SDK pattern)
  • AUTH uses raw key bytes in OP_AUTH frame (no length prefix, matching server protocol)
  • Consume push frames decoded as batches (msg_count:u16 | messages...)
  • FibpAdminClient added to test package with hand-rolled minimal protobuf for CreateQueueRequest (avoids a test protobuf dependency)
  • Integration tests (FilaClientTest, BatchClientTest, TlsAuthClientTest) guarded by @EnabledIf("serverAvailable") and skip cleanly when no binary is present; unit tests all pass

Test plan

  • All 21 unit tests pass (./gradlew test)
  • spotlessCheck passes (formatting enforced by Google Java Format)
  • CI integration tests pass against downloaded fila-server binary
  • TLS tests: verify withTls(), withTlsCaCert(), withTlsClientCert() (mTLS) all connect
  • Auth tests: verify withApiKey() sends AUTH frame and server accepts/rejects correctly

🤖 Generated with Claude Code


Summary by cubic

Replaced the gRPC/protobuf transport with FIBP (Fila Binary Protocol) over raw TCP/TLS while keeping the public FilaClient API the same. This removes all gRPC/protobuf deps, adds a single-socket multiplexed connection with heartbeat and AUTH, and includes stability/validation fixes.

  • New Features

    • Added FibpConnection: framing, handshake, correlation IDs, heartbeat scheduler, optional TLS, and AUTH via OP_AUTH.
    • Added FibpCodec: encode/decode for enqueue, batched consume push, ack/nack, and error frames; validates header count (<=255) and str16 length (<=65535).
    • Public FilaClient API unchanged; batcher groups messages by queue and sends one enqueue frame per queue; enqueueMany enforces a single target queue.
    • Replaced gRPC status with RpcException.Code; errors mapped from server error text.
    • Robustness: remove pending futures on consume timeout/interrupt; guard push handler exceptions to keep the reader thread alive; map batch timeouts to UNAVAILABLE; add a fallback catch in the batcher to resolve futures with INTERNAL on unexpected exceptions.
    • Tests use FibpAdminClient for queue creation (supports TLS/mTLS); README updated; version bumped to 0.3.0.
  • Migration

    • Update dependency to dev.faisca:fila-client:0.3.0.
    • Replace any uses of gRPC Status.Code with RpcException.Code.
    • build() now opens a connection; tests that constructed clients without a running server should guard or defer client creation.
    • Consume handlers run on the FIBP reader thread; avoid heavy or blocking work in the callback.
    • enqueueMany should target a single queue per call.

Written for commit 03bf792. Summary will update on new commits.

rewrite the java sdk transport layer to use fibp (fila binary protocol)
over raw tcp instead of grpc/protobuf.
- add FibpConnection: tcp socket with length-prefixed framing, handshake,
correlation-id multiplexing via ConcurrentHashMap + CompletableFuture,
heartbeat scheduler, and optional tls via SSLSocket
- add FibpCodec: wire encoding/decoding for enqueue, consume push batch,
ack, nack, and error frames (exact format from fila-core/src/fibp/wire.rs)
- rewrite FilaClient to use FibpConnection; remove all grpc/protobuf deps
- rewrite Batcher to use FibpConnection; groups messages by queue into
separate fibp frames (one queue name per enqueue frame)
- rewrite ConsumerHandle without grpc Context dependency
- update RpcException to define its own Code enum (no grpc Status.Code)
- remove ApiKeyInterceptor (auth now via fibp OP_AUTH frame)
- remove proto/ directory and grpc/protobuf gradle deps; bump to v0.3.0
- add FibpAdminClient in test package for createQueue (hand-rolled protobuf
encoding of CreateQueueRequest, avoids adding a test protobuf dependency)
- update TestServer to use FibpAdminClient instead of grpc admin stub
- update BuilderTest: remove tests that require a server connection (fibp
connects eagerly unlike grpc lazy channels); add address-parsing unit tests
- add @EnabledIf("serverAvailable") guard to FilaClientTest
- update TlsAuthClientTest to use RpcException.Code instead of grpc Status.Code

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

7 issues found across 17 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/main/java/dev/faisca/fila/FibpConnection.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FibpConnection.java:191">
P2: Remove the pending entry when the consume setup times out or is interrupted; otherwise the failed consume leaves a stale future in the pending map.</violation>
<violation number="2" location="src/main/java/dev/faisca/fila/FibpConnection.java:328">
P2: Guard push handlers so an exception doesn’t kill the reader thread and strand pending requests.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/FibpCodec.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FibpCodec.java:73">
P2: Guard the header count before writing the u8 field. Counts >255 wrap in writeByte and desynchronize the frame.</violation>
<violation number="2" location="src/main/java/dev/faisca/fila/FibpCodec.java:311">
P2: Validate str16 lengths before writing. Without a bounds check, strings longer than 65,535 bytes wrap in writeShort and corrupt the frame.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/FilaClient.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FilaClient.java:112">
P2: enqueueMany does not enforce that all messages target the same queue even though the FIBP frame encodes only the first queue name. Mixed-queue batches will silently send messages to the wrong queue.</violation>
</file>
<file name="src/test/java/dev/faisca/fila/TestServer.java">
<violation number="1" location="src/test/java/dev/faisca/fila/TestServer.java:88">
P2: createQueueWithApiKey now connects over a plain Socket via FibpAdminClient, but it is used immediately after startWithTls. This skips TLS/mTLS setup, so queue creation will fail against a TLS-enabled server.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/Batcher.java">
<violation number="1" location="src/main/java/dev/faisca/fila/Batcher.java:239">
P2: respFuture.get can throw InterruptedException/TimeoutException, but the generic catch maps them to INTERNAL and clears the interrupt. Handle these explicitly (restore interrupt + map timeout to UNAVAILABLE) so batched enqueue errors match sendSync behavior.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment threadsrc/main/java/dev/faisca/fila/FibpConnection.java
Comment threadsrc/main/java/dev/faisca/fila/FibpConnection.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/FibpCodec.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/FibpCodec.java
Comment threadsrc/main/java/dev/faisca/fila/FilaClient.java
Comment threadsrc/test/java/dev/faisca/fila/TestServer.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/Batcher.java
- FibpConnection: remove pending entry on consume timeout/interrupt to
prevent stale future accumulation in the pending map
- FibpConnection: guard push handler invocations so exceptions from the
user handler do not kill the reader thread and strand pending requests
- FibpCodec: validate header count <= 255 before writing u8 field
- FibpCodec: validate str16 string length <= 65535 before writing u16
- FilaClient.enqueueMany: validate all messages target the same queue —
FIBP enqueue frames encode one queue name at the request level
- Batcher.flushQueueBatch: handle InterruptedException and TimeoutException
explicitly; restore interrupt flag and map timeout to UNAVAILABLE
- FibpAdminClient: add TLS/mTLS support so createQueueWithApiKey works
against TLS-enabled servers
- TestServer.createQueueImpl: use TLS connection when server has TLS enabled

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 6 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/main/java/dev/faisca/fila/Batcher.java">
<violation number="1" location="src/main/java/dev/faisca/fila/Batcher.java:244">
P2: The generic catch-all was removed, so unexpected runtime exceptions (e.g., decodeEnqueueResponse failures) will now escape this method and leave the per-item futures unresolved. Add a fallback catch to map and complete all futures on any other exception.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment threadsrc/main/java/dev/faisca/fila/Batcher.java
without the fallback, unexpected runtime exceptions such as those from
decodeEnqueueResponse can escape flushQueueBatch and leave per-item
CompletableFuture instances unresolved, blocking callers indefinitely.
add a RuntimeException catch-all after the typed handlers that resolves
all futures with an INTERNAL error.
@vieiralucas
vieiralucas merged commit 6694a8e into mainMar 26, 2026
2 checks passed
Sign up for freeto 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.

1 participant

@vieiralucas
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: replace gRPC transport with FIBP binary protocol - #5

Merged
vieiralucas merged 3 commits into
mainfrom
feat/fibp-transport
Mar 26, 2026
Merged

feat: replace gRPC transport with FIBP binary protocol#5
vieiralucas merged 3 commits into
mainfrom
feat/fibp-transport

Conversation

@vieiralucas

@vieiralucasvieiralucas commented Mar 26, 2026

Copy link
Copy Markdown
Member

Summary

  • Replaces the gRPC/protobuf transport with FIBP (Fila Binary Protocol) over raw TCP/TLS
  • Removes all gRPC and protobuf dependencies from build.gradle (no runtime dependencies remain)
  • Adds FibpConnection — TCP socket with length-prefixed framing, handshake, correlation-ID multiplexing via ConcurrentHashMap + CompletableFuture, heartbeat scheduler, and optional TLS via SSLSocket
  • Adds FibpCodec — wire encoding/decoding matching fila-core/src/fibp/wire.rs exactly (enqueue, consume push batch, ack, nack, error frames)
  • Keeps the public FilaClient API identical: enqueue, enqueueMany, consume, ack, nack, close, Builder with all TLS/auth/batch options preserved
  • Batcher groups messages by queue before sending (one FIBP enqueue frame per queue name, since the frame-level field is per-queue)
  • RpcException.Code replaces io.grpc.Status.Code; error classification uses keyword matching on plain-text error payloads (matching the Rust SDK pattern)
  • AUTH uses raw key bytes in OP_AUTH frame (no length prefix, matching server protocol)
  • Consume push frames decoded as batches (msg_count:u16 | messages...)
  • FibpAdminClient added to test package with hand-rolled minimal protobuf for CreateQueueRequest (avoids a test protobuf dependency)
  • Integration tests (FilaClientTest, BatchClientTest, TlsAuthClientTest) guarded by @EnabledIf("serverAvailable") and skip cleanly when no binary is present; unit tests all pass

Test plan

  • All 21 unit tests pass (./gradlew test)
  • spotlessCheck passes (formatting enforced by Google Java Format)
  • CI integration tests pass against downloaded fila-server binary
  • TLS tests: verify withTls(), withTlsCaCert(), withTlsClientCert() (mTLS) all connect
  • Auth tests: verify withApiKey() sends AUTH frame and server accepts/rejects correctly

🤖 Generated with Claude Code


Summary by cubic

Replaced the gRPC/protobuf transport with FIBP (Fila Binary Protocol) over raw TCP/TLS while keeping the public FilaClient API the same. This removes all gRPC/protobuf deps, adds a single-socket multiplexed connection with heartbeat and AUTH, and includes stability/validation fixes.

  • New Features

    • Added FibpConnection: framing, handshake, correlation IDs, heartbeat scheduler, optional TLS, and AUTH via OP_AUTH.
    • Added FibpCodec: encode/decode for enqueue, batched consume push, ack/nack, and error frames; validates header count (<=255) and str16 length (<=65535).
    • Public FilaClient API unchanged; batcher groups messages by queue and sends one enqueue frame per queue; enqueueMany enforces a single target queue.
    • Replaced gRPC status with RpcException.Code; errors mapped from server error text.
    • Robustness: remove pending futures on consume timeout/interrupt; guard push handler exceptions to keep the reader thread alive; map batch timeouts to UNAVAILABLE; add a fallback catch in the batcher to resolve futures with INTERNAL on unexpected exceptions.
    • Tests use FibpAdminClient for queue creation (supports TLS/mTLS); README updated; version bumped to 0.3.0.
  • Migration

    • Update dependency to dev.faisca:fila-client:0.3.0.
    • Replace any uses of gRPC Status.Code with RpcException.Code.
    • build() now opens a connection; tests that constructed clients without a running server should guard or defer client creation.
    • Consume handlers run on the FIBP reader thread; avoid heavy or blocking work in the callback.
    • enqueueMany should target a single queue per call.

Written for commit 03bf792. Summary will update on new commits.

rewrite the java sdk transport layer to use fibp (fila binary protocol)
over raw tcp instead of grpc/protobuf.
- add FibpConnection: tcp socket with length-prefixed framing, handshake,
correlation-id multiplexing via ConcurrentHashMap + CompletableFuture,
heartbeat scheduler, and optional tls via SSLSocket
- add FibpCodec: wire encoding/decoding for enqueue, consume push batch,
ack, nack, and error frames (exact format from fila-core/src/fibp/wire.rs)
- rewrite FilaClient to use FibpConnection; remove all grpc/protobuf deps
- rewrite Batcher to use FibpConnection; groups messages by queue into
separate fibp frames (one queue name per enqueue frame)
- rewrite ConsumerHandle without grpc Context dependency
- update RpcException to define its own Code enum (no grpc Status.Code)
- remove ApiKeyInterceptor (auth now via fibp OP_AUTH frame)
- remove proto/ directory and grpc/protobuf gradle deps; bump to v0.3.0
- add FibpAdminClient in test package for createQueue (hand-rolled protobuf
encoding of CreateQueueRequest, avoids adding a test protobuf dependency)
- update TestServer to use FibpAdminClient instead of grpc admin stub
- update BuilderTest: remove tests that require a server connection (fibp
connects eagerly unlike grpc lazy channels); add address-parsing unit tests
- add @EnabledIf("serverAvailable") guard to FilaClientTest
- update TlsAuthClientTest to use RpcException.Code instead of grpc Status.Code

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

7 issues found across 17 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/main/java/dev/faisca/fila/FibpConnection.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FibpConnection.java:191">
P2: Remove the pending entry when the consume setup times out or is interrupted; otherwise the failed consume leaves a stale future in the pending map.</violation>
<violation number="2" location="src/main/java/dev/faisca/fila/FibpConnection.java:328">
P2: Guard push handlers so an exception doesn’t kill the reader thread and strand pending requests.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/FibpCodec.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FibpCodec.java:73">
P2: Guard the header count before writing the u8 field. Counts >255 wrap in writeByte and desynchronize the frame.</violation>
<violation number="2" location="src/main/java/dev/faisca/fila/FibpCodec.java:311">
P2: Validate str16 lengths before writing. Without a bounds check, strings longer than 65,535 bytes wrap in writeShort and corrupt the frame.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/FilaClient.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FilaClient.java:112">
P2: enqueueMany does not enforce that all messages target the same queue even though the FIBP frame encodes only the first queue name. Mixed-queue batches will silently send messages to the wrong queue.</violation>
</file>
<file name="src/test/java/dev/faisca/fila/TestServer.java">
<violation number="1" location="src/test/java/dev/faisca/fila/TestServer.java:88">
P2: createQueueWithApiKey now connects over a plain Socket via FibpAdminClient, but it is used immediately after startWithTls. This skips TLS/mTLS setup, so queue creation will fail against a TLS-enabled server.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/Batcher.java">
<violation number="1" location="src/main/java/dev/faisca/fila/Batcher.java:239">
P2: respFuture.get can throw InterruptedException/TimeoutException, but the generic catch maps them to INTERNAL and clears the interrupt. Handle these explicitly (restore interrupt + map timeout to UNAVAILABLE) so batched enqueue errors match sendSync behavior.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment threadsrc/main/java/dev/faisca/fila/FibpConnection.java
Comment threadsrc/main/java/dev/faisca/fila/FibpConnection.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/FibpCodec.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/FibpCodec.java
Comment threadsrc/main/java/dev/faisca/fila/FilaClient.java
Comment threadsrc/test/java/dev/faisca/fila/TestServer.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/Batcher.java
- FibpConnection: remove pending entry on consume timeout/interrupt to
prevent stale future accumulation in the pending map
- FibpConnection: guard push handler invocations so exceptions from the
user handler do not kill the reader thread and strand pending requests
- FibpCodec: validate header count <= 255 before writing u8 field
- FibpCodec: validate str16 string length <= 65535 before writing u16
- FilaClient.enqueueMany: validate all messages target the same queue —
FIBP enqueue frames encode one queue name at the request level
- Batcher.flushQueueBatch: handle InterruptedException and TimeoutException
explicitly; restore interrupt flag and map timeout to UNAVAILABLE
- FibpAdminClient: add TLS/mTLS support so createQueueWithApiKey works
against TLS-enabled servers
- TestServer.createQueueImpl: use TLS connection when server has TLS enabled

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 6 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/main/java/dev/faisca/fila/Batcher.java">
<violation number="1" location="src/main/java/dev/faisca/fila/Batcher.java:244">
P2: The generic catch-all was removed, so unexpected runtime exceptions (e.g., decodeEnqueueResponse failures) will now escape this method and leave the per-item futures unresolved. Add a fallback catch to map and complete all futures on any other exception.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment threadsrc/main/java/dev/faisca/fila/Batcher.java
without the fallback, unexpected runtime exceptions such as those from
decodeEnqueueResponse can escape flushQueueBatch and leave per-item
CompletableFuture instances unresolved, blocking callers indefinitely.
add a RuntimeException catch-all after the typed handlers that resolves
all futures with an INTERNAL error.
@vieiralucas
vieiralucas merged commit 6694a8e into mainMar 26, 2026
2 checks passed
Sign up for freeto 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.

1 participant

@vieiralucas
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: replace gRPC transport with FIBP binary protocol - #5

Merged
vieiralucas merged 3 commits into
mainfrom
feat/fibp-transport
Mar 26, 2026
Merged

feat: replace gRPC transport with FIBP binary protocol#5
vieiralucas merged 3 commits into
mainfrom
feat/fibp-transport

Conversation

@vieiralucas

@vieiralucasvieiralucas commented Mar 26, 2026

Copy link
Copy Markdown
Member

Summary

  • Replaces the gRPC/protobuf transport with FIBP (Fila Binary Protocol) over raw TCP/TLS
  • Removes all gRPC and protobuf dependencies from build.gradle (no runtime dependencies remain)
  • Adds FibpConnection — TCP socket with length-prefixed framing, handshake, correlation-ID multiplexing via ConcurrentHashMap + CompletableFuture, heartbeat scheduler, and optional TLS via SSLSocket
  • Adds FibpCodec — wire encoding/decoding matching fila-core/src/fibp/wire.rs exactly (enqueue, consume push batch, ack, nack, error frames)
  • Keeps the public FilaClient API identical: enqueue, enqueueMany, consume, ack, nack, close, Builder with all TLS/auth/batch options preserved
  • Batcher groups messages by queue before sending (one FIBP enqueue frame per queue name, since the frame-level field is per-queue)
  • RpcException.Code replaces io.grpc.Status.Code; error classification uses keyword matching on plain-text error payloads (matching the Rust SDK pattern)
  • AUTH uses raw key bytes in OP_AUTH frame (no length prefix, matching server protocol)
  • Consume push frames decoded as batches (msg_count:u16 | messages...)
  • FibpAdminClient added to test package with hand-rolled minimal protobuf for CreateQueueRequest (avoids a test protobuf dependency)
  • Integration tests (FilaClientTest, BatchClientTest, TlsAuthClientTest) guarded by @EnabledIf("serverAvailable") and skip cleanly when no binary is present; unit tests all pass

Test plan

  • All 21 unit tests pass (./gradlew test)
  • spotlessCheck passes (formatting enforced by Google Java Format)
  • CI integration tests pass against downloaded fila-server binary
  • TLS tests: verify withTls(), withTlsCaCert(), withTlsClientCert() (mTLS) all connect
  • Auth tests: verify withApiKey() sends AUTH frame and server accepts/rejects correctly

🤖 Generated with Claude Code


Summary by cubic

Replaced the gRPC/protobuf transport with FIBP (Fila Binary Protocol) over raw TCP/TLS while keeping the public FilaClient API the same. This removes all gRPC/protobuf deps, adds a single-socket multiplexed connection with heartbeat and AUTH, and includes stability/validation fixes.

  • New Features

    • Added FibpConnection: framing, handshake, correlation IDs, heartbeat scheduler, optional TLS, and AUTH via OP_AUTH.
    • Added FibpCodec: encode/decode for enqueue, batched consume push, ack/nack, and error frames; validates header count (<=255) and str16 length (<=65535).
    • Public FilaClient API unchanged; batcher groups messages by queue and sends one enqueue frame per queue; enqueueMany enforces a single target queue.
    • Replaced gRPC status with RpcException.Code; errors mapped from server error text.
    • Robustness: remove pending futures on consume timeout/interrupt; guard push handler exceptions to keep the reader thread alive; map batch timeouts to UNAVAILABLE; add a fallback catch in the batcher to resolve futures with INTERNAL on unexpected exceptions.
    • Tests use FibpAdminClient for queue creation (supports TLS/mTLS); README updated; version bumped to 0.3.0.
  • Migration

    • Update dependency to dev.faisca:fila-client:0.3.0.
    • Replace any uses of gRPC Status.Code with RpcException.Code.
    • build() now opens a connection; tests that constructed clients without a running server should guard or defer client creation.
    • Consume handlers run on the FIBP reader thread; avoid heavy or blocking work in the callback.
    • enqueueMany should target a single queue per call.

Written for commit 03bf792. Summary will update on new commits.

rewrite the java sdk transport layer to use fibp (fila binary protocol)
over raw tcp instead of grpc/protobuf.
- add FibpConnection: tcp socket with length-prefixed framing, handshake,
correlation-id multiplexing via ConcurrentHashMap + CompletableFuture,
heartbeat scheduler, and optional tls via SSLSocket
- add FibpCodec: wire encoding/decoding for enqueue, consume push batch,
ack, nack, and error frames (exact format from fila-core/src/fibp/wire.rs)
- rewrite FilaClient to use FibpConnection; remove all grpc/protobuf deps
- rewrite Batcher to use FibpConnection; groups messages by queue into
separate fibp frames (one queue name per enqueue frame)
- rewrite ConsumerHandle without grpc Context dependency
- update RpcException to define its own Code enum (no grpc Status.Code)
- remove ApiKeyInterceptor (auth now via fibp OP_AUTH frame)
- remove proto/ directory and grpc/protobuf gradle deps; bump to v0.3.0
- add FibpAdminClient in test package for createQueue (hand-rolled protobuf
encoding of CreateQueueRequest, avoids adding a test protobuf dependency)
- update TestServer to use FibpAdminClient instead of grpc admin stub
- update BuilderTest: remove tests that require a server connection (fibp
connects eagerly unlike grpc lazy channels); add address-parsing unit tests
- add @EnabledIf("serverAvailable") guard to FilaClientTest
- update TlsAuthClientTest to use RpcException.Code instead of grpc Status.Code

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

7 issues found across 17 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/main/java/dev/faisca/fila/FibpConnection.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FibpConnection.java:191">
P2: Remove the pending entry when the consume setup times out or is interrupted; otherwise the failed consume leaves a stale future in the pending map.</violation>
<violation number="2" location="src/main/java/dev/faisca/fila/FibpConnection.java:328">
P2: Guard push handlers so an exception doesn’t kill the reader thread and strand pending requests.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/FibpCodec.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FibpCodec.java:73">
P2: Guard the header count before writing the u8 field. Counts >255 wrap in writeByte and desynchronize the frame.</violation>
<violation number="2" location="src/main/java/dev/faisca/fila/FibpCodec.java:311">
P2: Validate str16 lengths before writing. Without a bounds check, strings longer than 65,535 bytes wrap in writeShort and corrupt the frame.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/FilaClient.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FilaClient.java:112">
P2: enqueueMany does not enforce that all messages target the same queue even though the FIBP frame encodes only the first queue name. Mixed-queue batches will silently send messages to the wrong queue.</violation>
</file>
<file name="src/test/java/dev/faisca/fila/TestServer.java">
<violation number="1" location="src/test/java/dev/faisca/fila/TestServer.java:88">
P2: createQueueWithApiKey now connects over a plain Socket via FibpAdminClient, but it is used immediately after startWithTls. This skips TLS/mTLS setup, so queue creation will fail against a TLS-enabled server.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/Batcher.java">
<violation number="1" location="src/main/java/dev/faisca/fila/Batcher.java:239">
P2: respFuture.get can throw InterruptedException/TimeoutException, but the generic catch maps them to INTERNAL and clears the interrupt. Handle these explicitly (restore interrupt + map timeout to UNAVAILABLE) so batched enqueue errors match sendSync behavior.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment threadsrc/main/java/dev/faisca/fila/FibpConnection.java
Comment threadsrc/main/java/dev/faisca/fila/FibpConnection.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/FibpCodec.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/FibpCodec.java
Comment threadsrc/main/java/dev/faisca/fila/FilaClient.java
Comment threadsrc/test/java/dev/faisca/fila/TestServer.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/Batcher.java
- FibpConnection: remove pending entry on consume timeout/interrupt to
prevent stale future accumulation in the pending map
- FibpConnection: guard push handler invocations so exceptions from the
user handler do not kill the reader thread and strand pending requests
- FibpCodec: validate header count <= 255 before writing u8 field
- FibpCodec: validate str16 string length <= 65535 before writing u16
- FilaClient.enqueueMany: validate all messages target the same queue —
FIBP enqueue frames encode one queue name at the request level
- Batcher.flushQueueBatch: handle InterruptedException and TimeoutException
explicitly; restore interrupt flag and map timeout to UNAVAILABLE
- FibpAdminClient: add TLS/mTLS support so createQueueWithApiKey works
against TLS-enabled servers
- TestServer.createQueueImpl: use TLS connection when server has TLS enabled

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 6 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/main/java/dev/faisca/fila/Batcher.java">
<violation number="1" location="src/main/java/dev/faisca/fila/Batcher.java:244">
P2: The generic catch-all was removed, so unexpected runtime exceptions (e.g., decodeEnqueueResponse failures) will now escape this method and leave the per-item futures unresolved. Add a fallback catch to map and complete all futures on any other exception.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment threadsrc/main/java/dev/faisca/fila/Batcher.java
without the fallback, unexpected runtime exceptions such as those from
decodeEnqueueResponse can escape flushQueueBatch and leave per-item
CompletableFuture instances unresolved, blocking callers indefinitely.
add a RuntimeException catch-all after the typed handlers that resolves
all futures with an INTERNAL error.
@vieiralucas
vieiralucas merged commit 6694a8e into mainMar 26, 2026
2 checks passed
Sign up for freeto 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.

1 participant

@vieiralucas
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: replace gRPC transport with FIBP binary protocol - #5

Merged
vieiralucas merged 3 commits into
mainfrom
feat/fibp-transport
Mar 26, 2026
Merged

feat: replace gRPC transport with FIBP binary protocol#5
vieiralucas merged 3 commits into
mainfrom
feat/fibp-transport

Conversation

@vieiralucas

@vieiralucasvieiralucas commented Mar 26, 2026

Copy link
Copy Markdown
Member

Summary

  • Replaces the gRPC/protobuf transport with FIBP (Fila Binary Protocol) over raw TCP/TLS
  • Removes all gRPC and protobuf dependencies from build.gradle (no runtime dependencies remain)
  • Adds FibpConnection — TCP socket with length-prefixed framing, handshake, correlation-ID multiplexing via ConcurrentHashMap + CompletableFuture, heartbeat scheduler, and optional TLS via SSLSocket
  • Adds FibpCodec — wire encoding/decoding matching fila-core/src/fibp/wire.rs exactly (enqueue, consume push batch, ack, nack, error frames)
  • Keeps the public FilaClient API identical: enqueue, enqueueMany, consume, ack, nack, close, Builder with all TLS/auth/batch options preserved
  • Batcher groups messages by queue before sending (one FIBP enqueue frame per queue name, since the frame-level field is per-queue)
  • RpcException.Code replaces io.grpc.Status.Code; error classification uses keyword matching on plain-text error payloads (matching the Rust SDK pattern)
  • AUTH uses raw key bytes in OP_AUTH frame (no length prefix, matching server protocol)
  • Consume push frames decoded as batches (msg_count:u16 | messages...)
  • FibpAdminClient added to test package with hand-rolled minimal protobuf for CreateQueueRequest (avoids a test protobuf dependency)
  • Integration tests (FilaClientTest, BatchClientTest, TlsAuthClientTest) guarded by @EnabledIf("serverAvailable") and skip cleanly when no binary is present; unit tests all pass

Test plan

  • All 21 unit tests pass (./gradlew test)
  • spotlessCheck passes (formatting enforced by Google Java Format)
  • CI integration tests pass against downloaded fila-server binary
  • TLS tests: verify withTls(), withTlsCaCert(), withTlsClientCert() (mTLS) all connect
  • Auth tests: verify withApiKey() sends AUTH frame and server accepts/rejects correctly

🤖 Generated with Claude Code


Summary by cubic

Replaced the gRPC/protobuf transport with FIBP (Fila Binary Protocol) over raw TCP/TLS while keeping the public FilaClient API the same. This removes all gRPC/protobuf deps, adds a single-socket multiplexed connection with heartbeat and AUTH, and includes stability/validation fixes.

  • New Features

    • Added FibpConnection: framing, handshake, correlation IDs, heartbeat scheduler, optional TLS, and AUTH via OP_AUTH.
    • Added FibpCodec: encode/decode for enqueue, batched consume push, ack/nack, and error frames; validates header count (<=255) and str16 length (<=65535).
    • Public FilaClient API unchanged; batcher groups messages by queue and sends one enqueue frame per queue; enqueueMany enforces a single target queue.
    • Replaced gRPC status with RpcException.Code; errors mapped from server error text.
    • Robustness: remove pending futures on consume timeout/interrupt; guard push handler exceptions to keep the reader thread alive; map batch timeouts to UNAVAILABLE; add a fallback catch in the batcher to resolve futures with INTERNAL on unexpected exceptions.
    • Tests use FibpAdminClient for queue creation (supports TLS/mTLS); README updated; version bumped to 0.3.0.
  • Migration

    • Update dependency to dev.faisca:fila-client:0.3.0.
    • Replace any uses of gRPC Status.Code with RpcException.Code.
    • build() now opens a connection; tests that constructed clients without a running server should guard or defer client creation.
    • Consume handlers run on the FIBP reader thread; avoid heavy or blocking work in the callback.
    • enqueueMany should target a single queue per call.

Written for commit 03bf792. Summary will update on new commits.

rewrite the java sdk transport layer to use fibp (fila binary protocol)
over raw tcp instead of grpc/protobuf.
- add FibpConnection: tcp socket with length-prefixed framing, handshake,
correlation-id multiplexing via ConcurrentHashMap + CompletableFuture,
heartbeat scheduler, and optional tls via SSLSocket
- add FibpCodec: wire encoding/decoding for enqueue, consume push batch,
ack, nack, and error frames (exact format from fila-core/src/fibp/wire.rs)
- rewrite FilaClient to use FibpConnection; remove all grpc/protobuf deps
- rewrite Batcher to use FibpConnection; groups messages by queue into
separate fibp frames (one queue name per enqueue frame)
- rewrite ConsumerHandle without grpc Context dependency
- update RpcException to define its own Code enum (no grpc Status.Code)
- remove ApiKeyInterceptor (auth now via fibp OP_AUTH frame)
- remove proto/ directory and grpc/protobuf gradle deps; bump to v0.3.0
- add FibpAdminClient in test package for createQueue (hand-rolled protobuf
encoding of CreateQueueRequest, avoids adding a test protobuf dependency)
- update TestServer to use FibpAdminClient instead of grpc admin stub
- update BuilderTest: remove tests that require a server connection (fibp
connects eagerly unlike grpc lazy channels); add address-parsing unit tests
- add @EnabledIf("serverAvailable") guard to FilaClientTest
- update TlsAuthClientTest to use RpcException.Code instead of grpc Status.Code

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

7 issues found across 17 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/main/java/dev/faisca/fila/FibpConnection.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FibpConnection.java:191">
P2: Remove the pending entry when the consume setup times out or is interrupted; otherwise the failed consume leaves a stale future in the pending map.</violation>
<violation number="2" location="src/main/java/dev/faisca/fila/FibpConnection.java:328">
P2: Guard push handlers so an exception doesn’t kill the reader thread and strand pending requests.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/FibpCodec.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FibpCodec.java:73">
P2: Guard the header count before writing the u8 field. Counts >255 wrap in writeByte and desynchronize the frame.</violation>
<violation number="2" location="src/main/java/dev/faisca/fila/FibpCodec.java:311">
P2: Validate str16 lengths before writing. Without a bounds check, strings longer than 65,535 bytes wrap in writeShort and corrupt the frame.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/FilaClient.java">
<violation number="1" location="src/main/java/dev/faisca/fila/FilaClient.java:112">
P2: enqueueMany does not enforce that all messages target the same queue even though the FIBP frame encodes only the first queue name. Mixed-queue batches will silently send messages to the wrong queue.</violation>
</file>
<file name="src/test/java/dev/faisca/fila/TestServer.java">
<violation number="1" location="src/test/java/dev/faisca/fila/TestServer.java:88">
P2: createQueueWithApiKey now connects over a plain Socket via FibpAdminClient, but it is used immediately after startWithTls. This skips TLS/mTLS setup, so queue creation will fail against a TLS-enabled server.</violation>
</file>
<file name="src/main/java/dev/faisca/fila/Batcher.java">
<violation number="1" location="src/main/java/dev/faisca/fila/Batcher.java:239">
P2: respFuture.get can throw InterruptedException/TimeoutException, but the generic catch maps them to INTERNAL and clears the interrupt. Handle these explicitly (restore interrupt + map timeout to UNAVAILABLE) so batched enqueue errors match sendSync behavior.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment threadsrc/main/java/dev/faisca/fila/FibpConnection.java
Comment threadsrc/main/java/dev/faisca/fila/FibpConnection.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/FibpCodec.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/FibpCodec.java
Comment threadsrc/main/java/dev/faisca/fila/FilaClient.java
Comment threadsrc/test/java/dev/faisca/fila/TestServer.java Outdated
Comment threadsrc/main/java/dev/faisca/fila/Batcher.java
- FibpConnection: remove pending entry on consume timeout/interrupt to
prevent stale future accumulation in the pending map
- FibpConnection: guard push handler invocations so exceptions from the
user handler do not kill the reader thread and strand pending requests
- FibpCodec: validate header count <= 255 before writing u8 field
- FibpCodec: validate str16 string length <= 65535 before writing u16
- FilaClient.enqueueMany: validate all messages target the same queue —
FIBP enqueue frames encode one queue name at the request level
- Batcher.flushQueueBatch: handle InterruptedException and TimeoutException
explicitly; restore interrupt flag and map timeout to UNAVAILABLE
- FibpAdminClient: add TLS/mTLS support so createQueueWithApiKey works
against TLS-enabled servers
- TestServer.createQueueImpl: use TLS connection when server has TLS enabled

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 6 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/main/java/dev/faisca/fila/Batcher.java">
<violation number="1" location="src/main/java/dev/faisca/fila/Batcher.java:244">
P2: The generic catch-all was removed, so unexpected runtime exceptions (e.g., decodeEnqueueResponse failures) will now escape this method and leave the per-item futures unresolved. Add a fallback catch to map and complete all futures on any other exception.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment threadsrc/main/java/dev/faisca/fila/Batcher.java
without the fallback, unexpected runtime exceptions such as those from
decodeEnqueueResponse can escape flushQueueBatch and leave per-item
CompletableFuture instances unresolved, blocking callers indefinitely.
add a RuntimeException catch-all after the typed handlers that resolves
all futures with an INTERNAL error.
@vieiralucas
vieiralucas merged commit 6694a8e into mainMar 26, 2026
2 checks passed
Sign up for freeto 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.

1 participant

@vieiralucas