Skip to content

feat(java): implement Async Connection Pooling using FixedChannelPool#2606

Open
rythm-sachdeva wants to merge 1 commit intoapache:masterfrom
rythm-sachdeva:feature/async-connection-pool
Open

feat(java): implement Async Connection Pooling using FixedChannelPool#2606
rythm-sachdeva wants to merge 1 commit intoapache:masterfrom
rythm-sachdeva:feature/async-connection-pool

Conversation

@rythm-sachdeva
Copy link

Description

Implements connection pooling for AsyncTcpConnection using Netty's FixedChannelPool to handle concurrent async operations efficiently.

Changes

  • Connection Pooling: Replaced single channel with FixedChannelPool for concurrent request handling
  • Pool Metrics: Added PoolMetrics class to track:
    • Active connections
    • Total requests and errors
    • Wait times (min/max/average in nanoseconds, microseconds, and milliseconds)
    • Error rate percentage
  • Configuration: Added TCPConnectionPoolConfig with builder pattern for customizing:
    • Max connections (default: 5)
    • Max pending acquires (default: 1000)
    • Acquire timeout (default: 3000ms)
  • Request Correlation: Implemented FIFO queue-based request/response matching using ConcurrentLinkedQueue
  • Broadcast Operations: Added broadcastAsync() method to execute commands across all pooled connections (useful for authentication)
  • Client Integration: Exposed pool configuration via AsyncIggyTcpClient.Builder.connectionPoolSize()

Implementation Details

  • Uses Netty's FixedChannelPool with ChannelHealthChecker.ACTIVE
  • Each channel has its own IggyResponseHandler with a response queue
  • Pool automatically releases channels after request completion
  • Handles connection errors gracefully with proper cleanup

Testing

  • Added integration test testConnectionPoolMetrics() to verify metrics tracking
  • Existing async integration tests validate concurrent operations
  • Pool properly handles concurrent sends and polls

Comment on lines +100 to +102
connectionPoolSize.orElse(5), // Default to 5 if not provided
1000, // maxPendingAcquires
connectionTimeout.map(Duration::toMillis).orElse(3000L) // map Duration to millis
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want to 1) make the params configurable? 2) or put them as static final constants?
Also seems we have the default provided by the builder already?

Copy link
Author

Choose a reason for hiding this comment

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

  1. Yes
  2. Yes
  3. Yes

Copy link
Member

Choose a reason for hiding this comment

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

@rythm-sachdeva please address this comment. The numeric values should be declared as static final. If any value has a default in the builder, it should be aligned in both places. Also, please remove the inline comments, the code is self-explanatory.


/**
* Connects to the server asynchronously.
* BroadCast Command to each connection
Copy link
Contributor

Choose a reason for hiding this comment

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

very minor nit: Broadcasts to keep it consistent :)

lastFuture.add(sendAsync(commandCode, payload.retainedDuplicate()));
}
// 2. Return the last Future (caller can treat this like a single request)
return lastFuture.get(lastFuture.size() - 1);
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if I understand correctly, but how does the last future guarantee on the behavior of all futures?

Copy link
Author

Choose a reason for hiding this comment

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

Does not guarantee, I assumed that if last request is fulfilled the previous requests have been successful. Though not a good approach. If there is any better approach you suggest I am happy to take feedback and implement it in an optimal way.

Comment on lines +76 to +77
// private final AtomicLong requestIdGenerator = new AtomicLong(0);
// private final ConcurrentHashMap<Long, CompletableFuture<ByteBuf>> pendingRequests = new ConcurrentHashMap<>();
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want to remove them?

Copy link
Author

Choose a reason for hiding this comment

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

Yes

Copy link
Member

Choose a reason for hiding this comment

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

If this code isn't being used, please remove it rather than leaving it commented out.

@mmodzelewski mmodzelewski linked an issue Jan 27, 2026 that may be closed by this pull request
20 tasks
@github-actions
Copy link

github-actions bot commented Feb 4, 2026

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs.

If you need a review, please ensure CI is green and the PR is rebased on the latest master. Don't hesitate to ping the maintainers - either @core on Discord or by mentioning them directly here on the PR.

Thank you for your contribution!

@github-actions github-actions bot added the stale Inactive issue or pull request label Feb 4, 2026
@hubcio hubcio changed the title feat(java): Implemented Async Connection Pooling using FixedChannelPool (#2232) feat(java): implement Async Connection Pooling using FixedChannelPool Feb 4, 2026
@github-actions github-actions bot removed the stale Inactive issue or pull request label Feb 5, 2026
@rythm-sachdeva rythm-sachdeva force-pushed the feature/async-connection-pool branch from 1dbbf20 to 2cdb131 Compare February 6, 2026 14:02
fix(java-sdk):Added Missing PoolMetrics and linting issues

fix(java):fixed connection error

fix(java):Fixed Linting Issues
@rythm-sachdeva rythm-sachdeva force-pushed the feature/async-connection-pool branch from 2cdb131 to 50e8a36 Compare February 7, 2026 06:56
@rythm-sachdeva
Copy link
Author

Hi @mmodzelewski Can you please review .

@mmodzelewski
Copy link
Member

Hi @mmodzelewski Can you please review .

Hey @rythm-sachdeva, I will, but I need some time. I might not get round to it until the beginning of next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Java SDK] Implement Connection Pooling for Async Client

3 participants