DRILL-4841: Use server event loop for web clients#565
DRILL-4841: Use server event loop for web clients#565sudheeshkatkam wants to merge 3 commits intoapache:masterfrom
Conversation
+ Merge DrillAutoCloseables and AuthCloseables + Remove unused imports + Expand * imports
+ Add DrillClient.Builder helper class to create DrillClient objects + Deprecate 8 constructors and DrillClientFactory + Reorganize and document DrillClient
| this.loop2 = TransportCheck.createEventLoopGroup(config.getInt(ExecConstants.BIT_SERVER_RPC_THREADS), "BitClient-"); | ||
| // Note that metrics are stored in a static instance | ||
| this.metrics = DrillMetrics.getRegistry(); | ||
| this.userLoopGroup = TransportCheck.createEventLoopGroup(config.getInt(ExecConstants.USER_SERVER_RPC_THREADS), |
There was a problem hiding this comment.
Please add a comment here stating that "userLoopGroup" threads will be used for "UserServerRPCThreads" and "ClientRPCThreads" in WebServer DrillClient instance.
paul-rogers
left a comment
There was a problem hiding this comment.
Mostly style/organization comments.
| * @throws RuntimeException if an Exception occurs; the Exception is | ||
| * wrapped by the RuntimeException | ||
| */ | ||
| public static void closeNoChecked(final AutoCloseable autoCloseable) { |
There was a problem hiding this comment.
closeUnchecked ?
But, we are "checking", the "checked" has to do with the Exception type.
Maybe cleanClose( ) for this function. Then, add a "closeSilently" to catch and ignore close exceptions. (The closeSilently is handy in the case when, say, a file is full, a write failed, and the close will also fail because it still can't flush pending buffers.) There are other functions to the to silent close, but might be handy to have them in one place.
| * <code> | ||
| * DrillClient client = DrillClient.newBuilder() | ||
| * .setConfig(...) | ||
| * .setIsDirectConnection(true) |
There was a problem hiding this comment.
setDirectConnection
The "setIs" form is rather awkward. The typical convention is:
setSomething( boolean flag )
boolean isSomething( )
| /** | ||
| * Helper class to construct a {@link DrillClient Drill client}. | ||
| */ | ||
| public static class Builder { |
There was a problem hiding this comment.
Seems useful/visible enough to justify being a top-level class, with its own file. That is, any reason not to say:
DrillClient client = new ClientBuilder( ) ... .build( );
Rather than:
DrillClient client = DrillClient.builder( ) ... .build( );
Because the Builder becomes the gateway to Drill, having extensive JavaDoc comments would be very helpful. See suggestions below.
| private boolean isDirectConnection = false; | ||
|
|
||
| /** | ||
| * Sets the {@link DrillConfig configuration} for this client. |
There was a problem hiding this comment.
Scenario? What is used by default? An empty config? One found on the class path?
What if I want to use the class-path (default) Drill config, but add my own customizations (as for tests)? Should we explain how to do this, or provide a method to help:
withExtraConfig( Config props )
| } | ||
|
|
||
| /** | ||
| * Sets the {@link DrillConfig configuration} for this client based on the given file. |
There was a problem hiding this comment.
Better to set this based on a File (or, for the trendy, Path) object, since that is the Java standard for local files.
Does this replace the default class-path config? Or, is this added to the defaults?
Can I use this with the above? Or, can I set either the config directory OR via a file? If one or the other, should we check that case and throw an IllegalStateException (unchecked) or the like?
| } | ||
|
|
||
| /** | ||
| * Sets whether the client will connect directly to the drillbit instead of going |
There was a problem hiding this comment.
Here (or in the class comment), explain how to use this with an embedded Drillbit. There is no ZK in that case. Would I use a direct connection for embedded?
If I choose to use embedded, where do I pass in the actual host:port information? Should this method take that info and, in so doing, implicitly set the "is direct" flag?
What is the default?
| .setConfig(drillbitContext.getConfig()) | ||
| .setClusterCoordinator(drillbitContext.getClusterCoordinator()) | ||
| .setAllocator(drillbitContext.getAllocator()) | ||
| .build(); |
There was a problem hiding this comment.
Should the builder be extended to also (optionally) do connect? Or, return a connect builder?
Here I'm thinking that it would be helpful to have a single builder gather things like the user name property and the connection string (which would seem to be a DrillClient parameter but is actually a connection property.)
That is, either:
DrillClient.builder( ) ...
.withUser( userName )
.connectTo( "myHost", 1234 )
.build( );
Or
DrillClient.builder( ) ...
.buildClient( )
.withUser( userName )
.connectTo( "myHost", 1234 )
.connect( );
| // Create a DrillClient | ||
| drillClient = new DrillClient(drillbitContext.getConfig(), | ||
| drillbitContext.getClusterCoordinator(), drillbitContext.getAllocator()); | ||
| drillClient = DrillClient.newBuilder() |
There was a problem hiding this comment.
Is the context something we should expose as part of our changes:
DrillbitContext context = ...
DrillClient client = DrillClient.builder( )
.fromContext( context )
.build( );
Doing the above might simplify test code.
| RemoteServiceSet serviceSet = RemoteServiceSet.getLocalServiceSet(); | ||
|
|
||
| try(Drillbit bit1 = new Drillbit(CONFIG, serviceSet); DrillClient client = new DrillClient(CONFIG, serviceSet.getCoordinator());){ | ||
| try(Drillbit bit1 = new Drillbit(CONFIG, serviceSet); |
There was a problem hiding this comment.
This pattern show up over and over. Should it just be moved into a function rather than as a duplicated "code injection" in a zillion files?
|
|
||
| this.ownsEventLoopGroup = builder.eventLoopGroup == null; | ||
| this.eventLoopGroup = !ownsEventLoopGroup ? builder.eventLoopGroup : | ||
| TransportCheck.createEventLoopGroup(config.getInt(ExecConstants.CLIENT_RPC_THREADS), "Client-"); |
There was a problem hiding this comment.
Factor this out into a separate function? Creating a thread pool seems distinct enough that it should be separate from setting config options...
|
@sudheeshkatkam, did you have a chance to address Pauls CR comments? |
@parthchandra please review (just the third commit).