Skip to content

DRILL-4841: Use server event loop for web clients#565

Open
sudheeshkatkam wants to merge 3 commits intoapache:masterfrom
sudheeshkatkam:DRILL-4841
Open

DRILL-4841: Use server event loop for web clients#565
sudheeshkatkam wants to merge 3 commits intoapache:masterfrom
sudheeshkatkam:DRILL-4841

Conversation

@sudheeshkatkam
Copy link
Copy Markdown
Contributor

@parthchandra please review (just the third commit).

Sudheesh Katkam added 3 commits August 10, 2016 15:14
+ 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),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please add a comment here stating that "userLoopGroup" threads will be used for "UserServerRPCThreads" and "ClientRPCThreads" in WebServer DrillClient instance.

Copy link
Copy Markdown
Contributor

@paul-rogers paul-rogers left a comment

Choose a reason for hiding this comment

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

Mostly style/organization comments.

* @throws RuntimeException if an Exception occurs; the Exception is
* wrapped by the RuntimeException
*/
public static void closeNoChecked(final AutoCloseable autoCloseable) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 {
Copy link
Copy Markdown
Contributor

@paul-rogers paul-rogers Oct 6, 2016

Choose a reason for hiding this comment

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

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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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-");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Factor this out into a separate function? Creating a thread pool seems distinct enough that it should be separate from setting config options...

@vvysotskyi
Copy link
Copy Markdown
Member

@sudheeshkatkam, did you have a chance to address Pauls CR comments?

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.

4 participants