Releases: line/armeria
armeria-0.21.2.Final
armeria-0.21.1.Final
armeria-0.21.0.Final
Warning: This release contains a lot of breaking changes. Read this release note carefully.
New features
- #201 Make
TomcatService
support Tomcat 8.5 - #172 Revamp the API to support content streaming and to hide Netty API from Armeria public API
- Provide a way to decorate all services
- Add
ServerBuilder.decorator()
that adds a decorator to all services in a server - Add
VirtualHostBuilder.decorator()
that adds a decorator too all services in aVirtualHost
- Add
Improvements
Known issues
- Unlike the previous releases, the public API of this release is not fully documented yet.
Breaking changes since 0.20.2
Having trouble with migration? Please feel free to ask us questions by creating a new issue or joining our Slack channel.
TL;DR
If you did not extend any classes in Armeria, you may be able to migrate relatively easily.
- Some methods will not return Netty
Future
anymore butCompletableFuture
. e.g.Server.start()
andstop()
- Replace the references to
ThriftService
withTHttpService
. - Use
HttpClient
in favor ofSimpleHttpClient
.
If you implemented any interfaces or extended any types provided by Armeria or you still have issues with migration, please read on.
Use Reactive Streams API to support HTTP content streaming
Previously, Armeria buffered full request and response in memory. It means it was not able to consume or produce a stream of large content. It also could not start processing HTTP headers until the complete HTTP content is received, which may affect latency negatively.
We chose Reactive Streams API as the foundation of HTTP content streaming because it is the de-facto standard API for implementing object streaming these days; RxJava, gRPC, Akka and Project Reactor are the notable adoptors.
Please watch Roland Kuhn's slides to learn more about Reactive Streams.
Armeria defines a new interface called com.linecorp.armeria.common.reactivestreams.RichPublisher
which adds a few useful operations on top of org.reactivestreams.Publisher
and uses it wherever potentially large stream is expected. com.linecorp.armeria.common.http.HttpRequest
and HttpResponse
are good examples that extend RichPublisher<HttpObject>
.
Armeria also provides an additional interface called com.linecorp.armeria.common.reactivestreams.Writer
, which is useful when you write a hot (or active) publisher in a reactive way:
// Not OK: We will see OutOfMemoryError!
Writer<HttpObject> out = ...;
for (;;) {
out.write(httpContent);
}
// OK: The callback we specified with onDemand() is executed only when
// the subscriber has demanded more HttpObjects.
void produceTraffic(Writer<HttpObject> out) {
out.write(httpContent);
out.onDemand(() -> produceTraffic(out));
}
produceTraffic(out);
Refrain from exposing Netty API in Armeria's public API
io.netty.util.concurrent.Future
andPromise
has been replaced withCompletableFuture
.- Armeria does not use the following types in its public API:
io.netty.buffer.ByteBuf
io.netty.handler.codec.http.HttpRequest
,HttpResponse
,HttpContent
and many related message typesio.netty.handler.codec.http.HttpHeaders
io.netty.handler.codec.http.HttpHeaderNames' and
HttpHeaderValues`io.netty.handler.codec.http.HttpResponseStatus
andHttpStatusClass
io.netty.handler.codec.http.FullHttpRequest
andFullHttpResponse
- See here for the complete list of the HTTP-related types introduced in this version.
- Armeria still uses Netty's
AsciiString
as header names because it's generic enough.
HTTP/2-centric HTTP API
Taking advantage of all the breaking changes introduced in this release, we designed our new HTTP API fit better with HTTP/2 than HTTP/1. Armeria will convert the inbound HTTP/1 messages to HTTP/2 automatically before they are served by your HTTP service or client implementation.
Redefine Client, Service and their context API
Previously, we shared one context type for both client and server side: ServiceInvocationContext
. This is potentially confusing and both client and server sides had to shoehorn their models into the common model provided by ServiceInvocationContext
.
Also, ServiceInvocationContext
assumed that a request is fully available when context is created. However, this is not true anymore with content streaming.
- Replace
ServiceInvocationContext
withcom.linecorp.common.RequestContext
- Add
ClientRequestContext
andServiceRequestContext
which extendRequestContext
- All timeout settings, maximum allowed content length and custom HTTP header options are now overridable via the setters of the context.
- Now that these options can be overridden by a client or a service, the option names have been prefixed with 'default'. e.g.
RESPONSE_TIMEOUT_MILLIS
toDEFAULT_RESPONSE_TIMEOUT_MILLIS
- Now that these options can be overridden by a client or a service, the option names have been prefixed with 'default'. e.g.
- Add
- Only expose the information that could be available when a request has just started rather than when a full request is ready.
- Add
RequestLog
andResponseLog
so that a client or a service fills the properties as they are available. A user will be notified viaRequestContext.requestLogFuture()
andresponseLogFuture()
when all necessary information is ready. - For example,
RequestContext.method()
property always returns the method at the session layer. That is, in a Thrift-over-HTTP call,ctx.method()
will not return"someThriftMethod"
anymore but only return"POST"
because such information is available only when the full request has been received. You can get the Thrift method name fromRequestLog
later when it's ready. - See
LogCollectingService
and its subtypes for real-world examples.
- Add
com.linecorp.armeria.server.Service
has been revamped:Service
now has type parameters.ServiceCodec
andServiceInvocationHandler
has been merged intoService
.Service.serve(ServiceRequestContext, Request)
serves a client request.
com.linecorp.armeria.client.Client
has been revamped:Client
now has type parameters.ClientCodec
andRemoteInvoker
have been merged intoClient
.Client.execute(ClientRequestContext, Request)
executes an invocation.
Revamp HttpService
with the new API
Previously, HttpService
assumed a request is fully available when it is invoked, which is not true anymore.
HttpService
is now an interface, and we added AbstractHttpService
which replaces the old HttpService
class.
Revamp ThriftService
with the new API
ThriftService
had tight coupling with HTTP session layer and we wanted to remove that.
ThriftService
has been deprecated; useTHttpService
instead.- You will not see many differences with
THttpService
, however, behind the scene, serving a Thrift call is achieved by twoService
s now:THttpService
andThriftCallService
:THttpService
translates an HTTP request into aThriftCall
and aThriftReply
into an HTTP response. (similar toServiceCodec
which has been removed in this release)ThriftCallService
delegates aThriftCall
to a stub implementation. (similar toServiceInvocationHandler
which has been removed in this release)- Note that the type parameters of
ThriftCallService
are notHttpRequest
andHttpResponse
anymore butThriftCall
andThriftReply
.
- Note that the type parameters of
- You will not see many differences with
Client-side renames
- Rename/replace
RemoteInvoker
to/withClientFactory
- Rename
RemoveInvokerOptions
,RemoteInvokerOption
andRemoteInvokerOptionValue
to `SessionOption...
armeria-0.20.2.Final
Bug fixes
- #200 Fix a bug where Armeria server closes a connection without sending a response when a Thrift request is malformed
armeria-0.20.1.Final
armeria-0.20.0.Final
armeria-0.19.0.Final
armeria-0.18.0.Final
armeria-0.17.0.Final
New features
- #156 Add 'the number of active requests' to metrics
- You will see a new property
activeRequests
if you are usingDropwizardMetricConsumer
.
- You will see a new property
- #159 Add doc strings to the JSON data generated by
DocService
DocService
will provide the comments in the IDL files if you put the.json
files produced by the nightly build of the official Thrift compiler into theMETA-INF/armeria/thrift
directory.- Note the comments are not visible in your browser yet. This is only a preparatory step for it.
- #160 Add
JettyService
- You can now embed Jetty as well as Tomcat!
- #163 Add
VirtualHost.defaultHostname()
andServer.defaultHostname()
- Try using
Server.defaultHostname()
to get the hostname of your machine reliably. TomcatService.forConnector()
does not require hostname anymore thanks to this new feature.
- Try using
Improvements
- #169 Log meaningful identifier of embedded Tomcat
Bug fixes
- #163 #167
TomcatService
does not callServer.destroy()
when it stops. - #166 Do not propagate
IdleStateEvent
to suppress misleading 'unexpected user event' message.
Clean-ups
armeria-0.16.1.Final
Bug fixes
- #158 Fix backward compatibility with old Armeria servers
- An Armeria client uses a
HEAD / HTTP/1.1
upgrade request for H1C-to-H2C upgrade by default again. - To use the HTTP/2 connection preface string as the default, set
com.linecorp.armeria.defaultUseHttp2Preface
totrue
.
- An Armeria client uses a