# Changelog

All notable changes to **apollo-blocking** will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.1]

### ✨ Features

#### introduce apollo-blocking ([#390](https://github.com/apollographql/apollo-platform-rs/pull/390)) by @BrynCooke

A new platform library crate for moving CPU-bound work — query planning, query
parsing, anything that holds a worker thread for more than a few microseconds —
off the async executor onto the tokio blocking thread pool.

The `.blocking_service()` terminal combinator on `tower::ServiceBuilder` accepts
a name, an optional cancellation token (typically a graceful-shutdown signal),
and a closure that receives the request and a per-call `CancellationToken`.
Cancellation propagates automatically when the future is dropped, covering
timeouts and client disconnects without extra wiring. Panics inside blocking
code propagate to the awaiting async task; pair with a top-level
`catch_panic`-style layer at your service entry point and a custom panic hook
for structured logging.

A span and a duration histogram are emitted on every dispatch, labelled with
the supplied name and the outcome (`success`, `cancelled`, or `panicked`). The
histogram's built-in count gives task throughput per outcome, so no separate
counter is needed. Always pair `blocking_service` with a concurrency-limit
layer; see the crate-level docs for sizing guidance.

```rust
use apollo_blocking::{CancellationToken, ServiceBuilderExt};
use apollo_qos::concurrency_limit::ConcurrencyLimitLayer;
use std::num::NonZeroUsize;
use tower::ServiceBuilder;

let svc = ServiceBuilder::new()
    .layer(ConcurrencyLimitLayer::new("query_planning", NonZeroUsize::new(32).unwrap()))
    .blocking_service("query_planning", None, |req: PlanRequest, ct: CancellationToken| {
        // CPU-bound work; poll ct.is_cancelled() at natural yield points.
        plan(req)
    });
```


