Skip to content

armeria-0.51.0

Choose a tag to compare

@trustin trustin released this 12 Jul 08:02

Breaking changes

  • #644 Replace SessionOptions with ClientFactoryBuilder

    // Before
    ClientFactory factory = new AllInOneClientFactory(SessionOptions.of(
            SessionOption.USE_HTTP2_PREFACE.newValue(true),
            SessionOption.USE_HTTP1_PIPELINING.newValue(true), ...);
    // After
    ClientFactory factory = new ClientFactoryBuilder()
            .useHttp2Preface(true)
            .useHttp1Pipelining(true)
            ...
            .build();
  • #619 #648 Change the parameters of JitterAddingBackoff from absolute values to rates

    // Before
    Backoff backoff = Backoff.exponential(1000, 60000).withJitter(1000); // 1-second jitter
    // After
    Backoff backoff = Backoff.exponential(1000, 60000).withJitter(0.3); // 30% jitter
  • #652 Add common EventLoopGroups and blocking task executor

    • Previously, unless specified explicitly, a ClientFactory and a Server had their own EventLoopGroups. From this release, we provide common EventLoopGroups via com.linecorp.armeria.common.CommonPools so that Armeria does not create unnecessarily large number of event loop threads.

      // Before: nCpuCore * 2 * 3 threads (s1, s2 and cf do not share the event loops)
      Server s1 = new ServerBuilder()...build();
      Server s2 = new ServerBuilder()...build();
      ClientFactory cf = new AllInOneClientFactory();
      // After: nCpuCore * 2 threads (s1, s2 and cf share the event loops)
      Server s1 = new ServerBuilder()...build();
      Server s2 = new ServerBuilder()...build();
      ClientFactory cf = new ClientFactoryBuilder()...build();
    • We also added ServerBuilder.worker/bossGroup() and ClientFactoryBuilder.workerGroup() so that you can specify an alternative EventLoopGroup easily. You'll find com.linecorp.armeria.common.util.EventLoopGroups.newEventLoopGroup() useful as well.

      Server s = new ServerBuilder()
              // 4 dedicated event loop threads.
              // 'true' means 'shut down the event loops when server stops.'
              .workerGroup(EventLoopGroups.newEventLoopGroup(4), true)
              ...
              .build();
      ClientFactory cf = new ClientFactoryBuilder()
              // 2 dedicated event loop threads.
              // 'true' means 'shut down the event loops when factory closes.'
              .workerGroup(EventLoopGroups.newEventLoopGroup(2), true)
              ...
              .build();
    • Similarly, we provide common blocking task executor via CommonPools, which was created per-Server until this release.

  • #667 Make StreamMessage implementations pass Reactive Streams TCK and clarify the behavior of StreamMessage.abort()

    • StreamMessage.subscribe() does not raise an exception immediately anymore. The subscriber is notified via onError() about subscription failure.
    • When a stream is aborted, AbortedStreamException is signaled to the subscriber's onError().
  • #645 #672 Allow more customization of LoggingService.

    • Separated log levels for request, response and failure.

    • Added customizable log sanitization

    • We changed the log level of failed responses from INFO to WARN.

      ServerBuilder sb = new ServerBuilder();
      sb.service(..., myService.decorate(new LoggingServiceBuilder()
              .requestLogLevel(LogLevel.INFO)
              .successfulResponseLogLevel(LogLevel.INFO)
              .failureResponseLogLevel(LogLevel.WARN)
              .newDecorator()));
  • #681 #677 Update dependencies

    • Brave 4.2.0 -> 4.5.1
    • completable-futures 0.3.0 -> 0.3.1
    • Dropwizard Metrics 3.2.2 -> 3.2.3
    • fastutil 7.2.1 -> 8.1.0
    • Netty 4.1.12 -> 4.1.13
    • Prometheus simpleclient 0.0.23 -> 0.0.24
    • Tomcat 8.5.15 -> 8.5.16 and 8.0.44 -> 8.0.45

New features

  • #680 Add HttpClientBuilder and HttpClient.of() which allows easier construction of HttpClient

    // Before:
    HttpClient c1 = Clients.newClient("none+http://example.com/");
    HttpClient c2 = new ClientBuilder("none+http://example.com/")
            .decorator(HttpRequest.class, HttpResponse.class, LoggingClient.newDecorator())
            .build(HttpClient.class);
    // After:
    // - No need to prepend 'none+'
    // - No need to specify HttpRequest.class` and HttpResponse.classs
    // - No need to specify HttpClient.class
    HttpClient c1 = HttpClient.of("http://example.com/");
    HttpClient c2 = new HttpClientBuilder("http://example.com/")
            .decorator(LoggingClient.newDecorator()) 
            .build();
  • #628 #660 Provide a way to specify a Backoff using a string expression

    // Useful when you want to make backoff strategy configurable:
    Backoff backoff = Backoff.of("exponential=1000:60000,jitter=0.3,maxAttempts=10");
  • #521 #662 Allow setting a custom request timeout handler

    @Get("/hello/:name")
    public HttpResponse hello(ServiceRequestContext ctx, @Param("name") name) {
        DefaultHttpResponse res = new DefaultHttpResponse();
        ctx.setRequestTimeoutHandler(() -> {
            res.respond(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, 
                        "A very late hello, %s.", name);
        });
        ...
    }
  • #657 Add content-security-policy and x-frame-options to HttpHeaderNames

Improvements

  • #675 Increase the chance of reusing idle client connections
  • #676 Clean up the closed channels more aggressively from DefaultKeyedChannelPool

Bug fixes

  • #651 #659 Fix PathMapping implementations to produce their loggerName and metricName correctly
  • #663 Only log an unexpected exception during authorization
  • #665 Fix EventLoop.terminationFuture() listener leak
  • #627 #656 Enable response timeout is enforced across the retries by RetryingClient