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

okhttp: add socketFactory method to channel builder #5378

Merged
merged 5 commits into from Feb 21, 2019

Conversation

ericgribkoff
Copy link
Contributor

This is mainly aimed at allowing Android users to force the OkHttp channel to use a particular network, via providing a socket factory obtained from android.net.Network#getSocketFactory(). The corresponding feature request from an internal user is at b/119564668.

@@ -156,6 +158,14 @@ public final OkHttpChannelBuilder transportExecutor(@Nullable Executor transport
return this;
}

/**
* Override the default {@link SocketFactory} used to create sockets.
Copy link
Member

Choose a reason for hiding this comment

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

Might be better to doc the behavior of null input.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -234,6 +245,7 @@ protected void handleNotInUse() {
// Client initiated streams are odd, server initiated ones are even. Server should not need to
// use it. We start clients at 3 to avoid conflicting with HTTP negotiation.
nextStreamId = 3;
this.socketFactory = socketFactory;
Copy link
Member

Choose a reason for hiding this comment

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

Can the field be final?

this.socketFactory = socketFactory == null ? SocketFactory.getDefault() : socketFactory;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The javadoc says:

Factory classes are specified by environment-specific configuration mechanisms. For example, the getDefault method could return a factory that was appropriate for a particular user or applet, and a framework could use a factory customized to its own purposes.

While I believe that in general the return value of SocketFactory.getDefault() is hard-coded and cannot change at runtime, this doesn't seem to be guaranteed by the API - so I went with the safer (?) approach of invoking it whenever used, which should mimic the existing behavior of new Socket(...)

Copy link
Member

Choose a reason for hiding this comment

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

That field can still be final. You might also need to test SocketFactory.getDefault() is used.

I think every single okhttp transport creates for only once a socket almost immediately after the transport is instantiated. It does not make much sense that the transport should be responsible to reflect any runtime change during the uncertain small gap between transport instantiation and transport start. Also if the runtime change is not synchronized with the serializingExecutor, socketFactoryToUse().createSocket() is not thread safe with the runtime change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is now final

@@ -156,6 +158,14 @@ public final OkHttpChannelBuilder transportExecutor(@Nullable Executor transport
return this;
}

/**
* Override the default {@link SocketFactory} used to create sockets.
*/
Copy link
Member

Choose a reason for hiding this comment

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

Add @since 1.20.0

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -156,6 +158,17 @@ public final OkHttpChannelBuilder transportExecutor(@Nullable Executor transport
return this;
}

/**
* Override the default {@link SocketFactory} used to create sockets. If the socket factory is not
* set, the value of {@link SocketFactory#getDefault} will be used.
Copy link
Member

Choose a reason for hiding this comment

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

nit: Let's hide the implementation detail. What about "If the socket factory is not set or set to null, a default one will be used"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -463,8 +487,8 @@ SSLSocketFactory createSocketFactory() {
private final boolean usingSharedExecutor;
private final boolean usingSharedScheduler;
private final TransportTracer.Factory transportTracerFactory;
@Nullable
private final SSLSocketFactory socketFactory;
@Nullable private final SocketFactory socketFactory;
Copy link
Member

Choose a reason for hiding this comment

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

Remove @Nullable, it's just like a random NPE from any library if SocketFactory.getDefault() were null.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@ericgribkoff ericgribkoff merged commit 6c32eaf into grpc:master Feb 21, 2019
@ericgribkoff ericgribkoff deleted the okhttp_socket_factory branch February 21, 2019 03:17
@lock lock bot locked as resolved and limited conversation to collaborators May 22, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants