-
Notifications
You must be signed in to change notification settings - Fork 15
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
Allow HTTP protocol selection #226
base: master
Are you sure you want to change the base?
Conversation
Thanks for the PR @jtjeferreira. I am currently on vacation. I will have a look next week. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks this looks very good to me.
What do you think of adding an integration test, which is using Http2 and also adding a paragraph in the Readme how Http2 can be enabled?
Do you know which AWS services support Http2?
@@ -145,21 +145,31 @@ object AkkaHttpClient { | |||
implicit val ec = executionContext.getOrElse(as.dispatcher) | |||
val mat: Materializer = SystemMaterializer(as).materializer | |||
|
|||
val mergedAttributeMap = attributeMap.merge(SdkHttpConfigurationOption.GLOBAL_HTTP_DEFAULTS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Except from Protocol
nothing else is used from the GLOBAL_HTTP_DEFAULTS
. Should we create a attributeMap with just the Protocol
in it, with a default to Http/1.1?
Otherwise it may be confusing, what other settings are taken from there and right now I would prefer to configure the Akka-Http client via its normal methods of configuration.
WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Except from Protocol nothing else is used from the GLOBAL_HTTP_DEFAULTS
The use of GLOBAL_HTTP_DEFAULTS
, was inspired in the NettyNioAsyncHttpClient, and I was planning to submit another PR that reads other attributes from there like CONNECTION_TIMEOUT
, MAX_CONNECTIONS
, etc...
I would prefer to configure the Akka-Http client via its normal methods of configuration.
I understand right now that configuration is done via the normal methods of configuration i.e typesafe config library, but what are your thoughts about changing that to use the attributeMap? Asking because I see some specific clients configuring specific options like KinesisHttpConfigurationOptions and you can find other examples here
Maybe we should honor those...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed the use GLOBAL_HTTP_DEFAULTS
and SdkHttpConfigurationOption
and added a simple protocol field to the builder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I created the issue #232 to track your idea with the config changes.
I tried that but only localstack supports http/2...
I could not find any documentation except https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http2.html, and its mention to kinesis using http2. However if I do |
Do you understand what is the issue with the CI? |
…han 10s to boot 11:04:01.130 [pool-1-thread-1] INFO t.a.1.0 - Container adobe/s3mock:2.13.0 is starting: 85d5881648cb02a95ecc3d406cf0b70ca7a6638c42a0d5e1f800c783479ee14e 11:04:11.530 [pool-1-thread-1] INFO t.a.1.0 - Container adobe/s3mock:2.13.0 started in PT10.436S
Hi @matsluni, I added some tests and improved the README |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @jtjeferreira, thanks for all the effort, this looks really good already. I think with the attributeMap you accidently removed a bit too much code.
private val connectionPoolSettings: Option[ConnectionPoolSettings] = None) extends SdkAsyncHttpClient.Builder[AkkaHttpClientBuilder] { | ||
private val connectionPoolSettings: Option[ConnectionPoolSettings] = None, | ||
private val protocol: HttpProtocol = HttpProtocols.`HTTP/1.1` | ||
) extends SdkAsyncHttpClient.Builder[AkkaHttpClientBuilder] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems with your latest refactoring here, the whole attributeMap
code is accidently gone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can also use a new withProtocol(HttpProtocol)
builder method to set the protocol?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems with your latest refactoring here, the whole attributeMap code is accidently gone.
the removal of the whole attributeMap
code was on purpose. let's explore that in #232
Maybe we can also use a new
withProtocol(HttpProtocol)
builder method to set the protocol?
yes I can do that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems with your latest refactoring here, the whole attributeMap code is accidently gone.
the removal of the whole
attributeMap
code was on purpose. let's explore that in #232
ok, but now I realize the README and tests don't make sense 🤦
} | ||
|
||
def withClient(testCode: DynamoDbAsyncClient => Any): Any = { | ||
private def withClient(attributeMap: AttributeMap = AttributeMap.empty())(testCode: DynamoDbAsyncClient => Any): Any = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
fix tests to use withProtocol instead of attributeMap
@matsluni ready for re-review |
I just found this: https://doc.akka.io/docs/akka-http/current/client-side/http2.html. I am wondering now, if our approach here is not really the thing we expect it to do? |
You mean any particular section?
Honestly, I am not sure either what to expect. I think that setting the protocol in the Also since this is an opt-in setting and we don't change anything for existing clients, I think this is a safe PR... I started exploring the internals of this library because I am having some issues with random connection closures, but I think #228 is much more promising in that regard. So if you are unsure about this PR, we can close it... |
Hi @jtjeferreira, I tried the approach I mentioned above in this branch: https://github.com/matsluni/aws-spi-akka-http/tree/protocol_other_approach. What do you think about this? The local tests using Http/2 are now do not finish anymore and therefore I commented them out. Actually, I would expect that the local tests using Http/2 are not working, as the local test services are not exposing Http/2 functionality (TLS etc). |
I don't think we should use the "Connection-Level Client-Side API" (i.e Besides the use of the def singleRequest(connection: Flow[HttpRequest, HttpResponse, Any], bufferSize: Int = 100): HttpRequest => Future[HttpResponse] = {
req => {
Source.single(req)
.via(connection)
.runWith(Sink.head)
}
}
The local tests are failing because we are not setting the port. We need to do Http()
.connectionTo(request.request().host())
.toPort(request.request().port())
.http2()
You can have HTTP/2 without TLS, and akka supports this with if (protocol == HttpProtocols.`HTTP/2.0`) {
val baseConnection = Http().connectionTo(request.request().host()).toPort(request.request().port())
val connection = request.request().protocol() match {
case "http" => baseConnection.http2WithPriorKnowledge()
case "https" => baseConnection.http2()
case _ => throw new IllegalArgumentException("Unsupported protocol")
}
val dispatch = singleRequest(connection)
runner.run(
() => dispatch(akkaHttpRequest),
request.responseHandler()
)
} all test are green except:
|
After writing the above comment, and looking at the debug logs of tests I realized that my approach of just setting the my approach
your approach
So I agree that we need to use the "Connection-Level Client-Side API", but we need to find a way so that the connection is not recreated every time... |
Honestly, I think we can close this, and revisit this when akka-http provides http/2 support in the "Request-Level Client-Side API" |
@jtjeferreira @matsluni I logged apache/pekko-http#483 - is this the missing feature that you need? |
My last comment referred to another limitation:
i.e currently http/2 is only supported at the Connection-Level API: val connectionFlow: Flow[HttpRequest, HttpResponse, Future[Http.OutgoingConnection]] =
Http().connectionTo("localhost").http2() but it should support the Request-Level API: val httpResponseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "http://localhost"))
//hipotethical API
val http2ResponseFuture: Future[HttpResponse] = Http2().singleRequest(HttpRequest(uri = "http://localhost")) |
Allow HTTP protocol selection
fixes #225