Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change getStreams to use multiple clients #19

Open
wants to merge 19 commits into
base: flight-jdbc-driver
Choose a base branch
from

Conversation

vfraga
Copy link
Collaborator

@vfraga vfraga commented Mar 23, 2022

This is currently just a draft but it tries to address the issue of only using a single client to grab multiple streams.
It uses Apache Pools to pool the clients keyed to their location correspondingly.

@vfraga vfraga added the enhancement New feature or request label Mar 23, 2022
@vfraga vfraga self-assigned this Mar 23, 2022
private final AtomicInteger clientCounter = new AtomicInteger();

public KeyedFlightSqlClientObjectPoolFactory(final BufferAllocator parentAllocator) {
super();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: let's avoid default super calls.


public void closeAllocator() {
parentAllocator.getChildAllocators().forEach(BufferAllocator::close);
parentAllocator.close();
Copy link
Collaborator

Choose a reason for hiding this comment

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

I am not sure about closing the parent allocator here... I don't see a call to close() being removed which means prior to this patch we were either leaking an allocator or we are double-closing this.


public class KeyedFlightSqlClientObjectPool extends GenericKeyedObjectPool<Location, FlightSqlClient> {

public KeyedFlightSqlClientObjectPool(KeyedPooledObjectFactory<Location, FlightSqlClient> factory) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

The casting of the factory to call a close method on it is weird.
Instead, you can make this class own the allocator:

  • Have the allocator be the parameter to the constructor.
  • call super(new KeyedFlightSql...()) and have that take in the allocator
  • override close() in this class, and move all the allocator cleanup there.

@Override
public synchronized void close() {
((KeyedFlightSqlClientObjectPoolFactory) getFactory()).closeAllocator();
super.close();
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you should actually call super.close() first to clean up the clients which are depending on the allocator, then clean up the allocator. (Normally the right thing to do is do child class clean-up, then base class clean-up but I think the logic needs to be different in this scenario).

}
final Location location = locations.get(0); // purposefully discard other locations

logger.info(String.format("Getting a client for location %s.", location));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Don't use String.format() with loggers. This executes the work to generate a string, even if logging is off.
Use the logger directly. Note that placeholders are curly braces in SLF4J eg:
logger.info("Getting client for location {}.", location);

please fix this throughout the PR.

flightSqlClient = flightSqlClientPool.borrowObject(location);
} catch (final NoSuchElementException e) {
try {
flightSqlClientPool.addObject(location);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would think this happens automatically rather than needing try/catch.

}

allStreams.add(flightSqlClient.getStream(endpoint.getTicket(), getOptions()));
flightSqlClientPool.returnObject(location, flightSqlClient);
Copy link
Collaborator

Choose a reason for hiding this comment

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

We cannot return the client to the pool until we are done getting the stream. Otherwise it allows another query being executed to re-use the client while it's still being used.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe we can write an auto-closeable wrapper on top of FlightStream that returns to the pool on closure.

Abner Eduardo Ferreira and others added 19 commits March 29, 2022 10:54
* Remove scope from 'hamcrest' dependency on java/pom.xml

* Use flight top-level module on parent pom.xml instead of declaring each one

* Avoid using getStatement inside StatementContext methods

* Make StatementContext.getQuery() return String

* Minor fixes on pom.xml

* Move 'os-maven-plugin' to parent pom.xml

* Update protobuf generation on pom.xml files

* Use ClassLoader#getResource to get network.properties on TestFlightSql

* Bind to any ephemeral port on TestFlightSql

* Move JDBC-Arrow type default conversion from JdbcToArrowConfig to JdbcToArrowUtils

* Micro-optimization: initialize ArrayList with the right size

* Fix null-check on PreparedStatement#setParameters

* Avoid wrapping vector into a ImmutableList and then into an ArrayList on FlightSqlExample#getTablesRoot

* Remove null-check on VectorSchemaRoot on FlightSqlClient#setParameters()

* Remove the need of separate cache for ResultSets

* Add missing 'final' modifiers
…les and query execution methods. (apache#226)

This add an auxiliary class FlightSqlColumnMetadata meant to read and write known metadata for Arrow schema fields, such as CATALOG_NAME, SCHEMA_NAME, TABLE_NAME, PRECISION, SCALE, IS_AUTO_INCREMENT, IS_CASE_SENSITIVE, IS_READ_ONLY and IS_SEARCHABLE.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
5 participants