> ## Documentation Index
> Fetch the complete documentation index at: https://docs.markpdf.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Streaming y trabajos asincrónicos

> Consuma /convert/stream y maneje 202 (auto-async) con markpdf-cpp.

# Streaming y trabajos asincrónicos

Como en el resto de SDK, existen dos mecanismos diferenciados:

1. **Transmisión de respuesta** (`/convert/stream`, `/convert/stream-from-url`): fragmentos de Markdown progresivo mediante devolución de llamada.
2. **Trabajos por saturación** (`202`): la solicitud se pone en cola cuando todos los backends están ocupados. Consulte [`GET /jobs/{id}`](/docs/public/es/api/jobs).

## Transmitiendo con `convertStream`

`markpdf-cpp` no expone corrutinas de forma predeterminada (para mantener la compatibilidad con C++17); la transmisión se modela con una devolución de llamada invocada en el mismo hilo durante la duración de la solicitud HTTP subyacente (implementada con `CURLOPT_WRITEFUNCTION`):

```cpp theme={null}
#include <markpdf/client.hpp>
#include <iostream>

markpdf::Client client("YOUR_API_KEY");

markpdf::StreamOptions opts;
opts.filename = "report.pdf";
opts.slim = true;

client.convertStream("report.pdf", markpdf::StreamSource::File,
    [](std::string_view chunk) {
        std::cout << chunk;
    },
    opts);
```

<CodeGroup>
  ```cpp Local file theme={null}
  client.convertStream("report.pdf", markpdf::StreamSource::File, onChunk, opts);
  ```

  ```cpp Desde URL theme={null}
  opts.filename.clear();
  client.convertStream(
      "https://bucket.example.com/report.pdf?sig=...",
      markpdf::StreamSource::Url, onChunk, opts);
  ```

  ```cpp Acumulando en un buffer theme={null}
  std::string full;
  client.convertStream("report.pdf", markpdf::StreamSource::File,
      [&full](std::string_view chunk) { full.append(chunk); },
      opts);
  // `full` contains the entire Markdown at the end of the call
  ```
</CodeGroup>

### Ejecutar en un hilo separado (no bloquear el hilo principal)

```cpp theme={null}
#include <thread>

std::thread worker([&client, &opts]() {
    client.convertStream("report.pdf", markpdf::StreamSource::File,
        [](std::string_view chunk) { publish(chunk); },
        opts);
});
worker.join();
```

`Client` es seguro de usar desde otro hilo siempre que no comparta la misma llamada en curso entre hilos.

### `StreamSlimStrategy`

```cpp theme={null}
opts.strategy = markpdf::StreamSlimStrategy::Sampled; // default
```

* `Off`: streaming puro por página, sin detección de ruido. TTFB mínimo.
* `Sampled` (predeterminado): muestra las primeras páginas y luego genera por página.
* `Full`: materializa el documento completo antes de su emisión. Mejor limpieza, peor TTFB.

Consulte [Parámetros](/docs/public/es/api/parameters#streaming-only-parameters).

<Note />

## Empleos por saturación (202)

Por defecto (`opts.autoPoll = true`), `convertFile` y `convertFromUrl` bloquean el hilo que los llama hasta que finaliza el trabajo:

```cpp theme={null}
markpdf::ConvertOptions opts; // autoPoll = true por default
auto result = client.convertFile("report.pdf", opts); // puede tardar más si hubo 202
```

### Manual de encuestas

```cpp theme={null}
markpdf::ConvertOptions opts;
opts.autoPoll = false;

auto result = client.convertFile("report.pdf", opts);
if (!result && result.error().kind == markpdf::ErrorKind::JobQueued) {
    std::string jobId = result.error().jobId.value();
    markpdf::JobStatus status;
    do {
        std::this_thread::sleep_for(std::chrono::seconds(5));
        auto poll = client.getJob(jobId);
        if (!poll) throw std::runtime_error(poll.error().detail);
        status = poll.value();
    } while (status.status == markpdf::JobState::Queued ||
             status.status == markpdf::JobState::Processing);

    if (status.status == markpdf::JobState::Completed) {
        std::string markdown = status.body.value();
    } else {
        throw std::runtime_error(status.error.value());
    }
}
```

<Tip>
  En condiciones de carga normales, no verá `202`; solo sucede cuando todos los backends están saturados. `autoPoll = true` (el predeterminado) ya lo cubre de forma transparente, incluido en el hilo que realiza la llamada.
</Tip>

<Warning>
  Los resultados de los trabajos completados caducan en aproximadamente 1 hora. Si guarda un `jobId` para más tarde y `getJob` devuelve `404` (asignado a `MarkpdfError` con `statusCode == 404`), reenvíe la conversión original.
</Warning>
