# 1.7.4

## Features

### Tracing plugin

A new `:tracing` plugin was introduced. It adds support for a new option, `:tracer`, which accepts an object which responds to the following callbacks:

* `#enabled?(request)` - should return true or false depending on whether tracing is enabled
* `#start(request)` - called when a request is about to be sent
* `#finish(request, response)` - called when a response is received
* `#reset(request)` - called when a request is being prepared to be resent, in cases where it makes sense (i.e. when a request is retried).

You can pass chain several tracers, and callbacks will be relayed to all of them:

```ruby
HTTP.plugin(:tracing).with(tracer: telemetry_platform_tracer).with(tracer: telemetry2_platform_tracer)
```

This was developed to be the foundation on top of which the datadog and OTel integrations will be built.

## Improvements

* try fetching response immediately after send the request to the connection; this allows returning from errors much earlier and bug free than doing another round of waits on I/O.
* when a connection is reconnected, and it was established the first time that the peer can accept only 1 request at a time, the connection will keep that informaation and keep sending requests 1 at a time afterwards.

## Bugfixes

* fix regression from introducing connection post state transition callbacks, by foregoing disconnect when there's pending backlog.
* transition requests to `:idle` before routing them to a different connection on merge (this could possibly leave dangling timeout callbacks otherwise).
* `:brotli` plugin was integrated with the stream writer component which allows writing compressed payload in chunks.
* `:brotli` plugin integrates with the `brotli` gem v0.8.0, which fixed an issue dealing with large payload responses due to the lack of support for decoding payloads in chunks.
* http1 parser: reset before early returning on `Upgrade` responses (it was left in an invalid "parsing headers", which in the case of a keep-alive connection, would cause the next request to fail being parsed).
* `datadog` adapter: fixed initialization of the request start time after connections were opened (it was being set to connection initialization time every time, instead of just on the first request before connection is established).
* parsers: also reroute non-completed in-flight requests back to the connection so they can be retried (previously, only pending requests were).
* `:proxy` plugin: do not try disconnecting unnecessarily when resetting may already do so (if conditions apply).
* `:proxy` plugin: removed call to unexisting `#reset!` function.
* `:proxy` plugin: also close wrapped sockets.
* connection: on force_close, move connection disconnection logic below so that, if requests are reenqueued from the parser, this can be halted.
* connection: when transition to `:idle`, reenqueue requests from parser before resetting it.
* implement `#lazy_resolve` on resolvers, as when they're picked from the selector (instead of from the pool), they may not be wrapped by a Multi proxy.
* allow resolvers transitioning from `:idle` to `:closed` and forego disconnecting when the resolver is not able to transition to `:closed` (which protects from a possible fiber scheduler context switch which changed the state under the hood).