
# 状态修剪

随着工作流经过许多步骤，累积的状态可能会变得很大。状态修剪会自动移除较早步骤的输出，使状态 JSON 保持在可控范围内，同时保留重要数据。

## 启用状态修剪

在工作流构建器上调用 `prune_state_after()`。参数是需要保留其输出的近期步骤数量：

```php
use Queuety\Queuety;

Queuety::workflow( 'long_pipeline' )
    ->then( StepA::class )
    ->then( StepB::class )
    ->then( StepC::class )
    ->then( StepD::class )
    ->then( StepE::class )
    ->prune_state_after( 2 )
    ->dispatch( [ 'input' => $data ] );
```

设置 `prune_state_after( 2 )` 后，步骤 D 完成时，步骤 A 和 B 的输出会从状态中移除。步骤 C 和 D（最近的两个步骤）会保留。

## 修剪的工作方式

启用状态修剪后，Queuety 会在保留的 `_step_outputs` 数组中记录每个步骤向状态添加的键。进入新步骤后，会移除早于阈值的步骤所引入的键。

例如，使用 `prune_state_after( 2 )` 时：

```
After step 0 (StepA): state has keys from StepA + initial payload
After step 1 (StepB): state has keys from StepA + StepB + initial payload
After step 2 (StepC): state has keys from StepA + StepB + StepC + initial payload
  -> prune: StepA output removed (only 2 most recent kept)
After step 3 (StepD): state has keys from StepB + StepC + StepD + initial payload
  -> prune: StepB output removed
```

## 保留的内容

Queuety 永远不会修剪以 `_` 开头的保留键，例如 `_steps`、`_queue`、`_priority`、`_max_attempts`、`_on_cancel`、`_prune_state_after` 和 `_step_outputs`。传递给 `dispatch()` 的初始负载键也会保留，因为它们一开始就不会被跟踪为步骤输出。除此之外，Queuety 会根据你配置的阈值保留最近 N 个步骤的输出。

## 适用场景

对于包含许多步骤且每个步骤生成的数据后续步骤并不真正需要的工作流，状态修剪很有用。常见例子包括每一步只需要前一两个步骤输出的长流水线、会生成庞大中间结构的 ETL 工作流，以及原本会不断累积重复状态的递归或重复工作流。如果工作流只有几个步骤，或者后续步骤仍依赖早期输出，通常完全不需要修剪。

## 默认行为

状态修剪默认处于禁用状态。`prune_state_after()` 方法接受一个整数参数。不带参数调用时，默认值为 2：

```php
->prune_state_after()     // keeps the 2 most recent step outputs
->prune_state_after( 5 )  // keeps the 5 most recent step outputs
```
