
# Разклоняване на работен поток

Queuety може да разклони работещ работен поток в напълно независимо копие. Разклоненият работен поток започва от същата стъпка и със същото състояние като първоначалния, но след това двата работни потока продължават независимо. Промените в единия не засягат другия.

## Разклоняване на работен поток

### PHP API

Извикайте `Queuety::fork_workflow()` с идентификатора на работния поток. Той връща новия идентификатор на работния поток:

```php
use Queuety\Queuety;

$forked_id = Queuety::fork_workflow( $workflow_id );
```

### CLI

```bash
wp queuety workflow fork <id>
```

| Опция | Описание |
|---|---|
| `<id>` | ИД на работния поток за разклоняване (задължително) |

```bash
wp queuety workflow fork 42
# Success: Workflow #42 forked. New workflow ID: 43.
```

## Как работи

При разклоняване на работен поток:

1. Редът на първоначалния работен поток се заключва и прочита
2. Вмъква се нов ред за работен поток със същото състояние, дефиниции на стъпките и текуща стъпка
3. Името на новия работен поток е `{original_name}_fork_{timestamp}`
4. Текущата стъпка се добавя в опашката за разклонения работен поток
5. Записва се събитие в регистъра `workflow_forked` както за първоначалния, така и за разклонения работен поток
6. Първоначалният работен поток продължава да се обработва както обикновено

Разклоненият работен поток е напълно независим. Той има собствен идентификатор, собствено копие на състоянието и собствени записи в опашката със задачи. От момента на разклоняване всеки работен поток може да се развива по свой път.

## Случаи на употреба

### A/B тестване на обработчици на стъпки

Разклонете работен поток, за да тествате два различни варианта на предстояща стъпка:

```php
// Original workflow will use the existing CallLLMHandler (GPT-4).
// Fork it to test with a different handler.
$forked_id = Queuety::fork_workflow( $workflow_id );

// Modify the forked workflow's state to use a different model.
// (Update the state via a custom step or direct DB update.)
```

### Анализ на сценарии

Разклонете работен поток при точка за вземане на решение, за да разгледате различни пътища:

```php
// Workflow is at step 3, about to process data.
// Fork it so we can try two different processing strategies.
$fork_a = Queuety::fork_workflow( $workflow_id );
$fork_b = Queuety::fork_workflow( $workflow_id );
```

Всяко разклонение продължава със същото входно състояние, но може да бъде променено така, че да следва различен път.

### Паралелни експерименти

Когато работният поток достигне момент, в който искате да изпробвате няколко подхода паралелно, разклонете го за всеки подход и сравнете резултатите, след като всички разклонения приключат.

## Проследяване на разклоненията

Събитието в регистъра на всеки работен поток съдържа препратка към другия:

- При първоначалния: `context.forked_workflow_id` сочи към новия работен поток
- При разклонението: `context.forked_from_workflow_id` сочи към първоначалния

Потърсете в регистрите всички разклонения на даден работен поток:

```php
$logs = Queuety::logger()->for_workflow( $workflow_id );

foreach ( $logs as $entry ) {
    if ( 'workflow_forked' === $entry['event'] ) {
        $context = json_decode( $entry['context'] ?? '{}', true );
        // $context['forked_workflow_id'] is the new workflow
    }
}
```

## Ограничения

- Разклоненият работен поток не наследява историята на регистъра на събитията от първоначалния. Той започва с празен регистър на събитията.
- Връзките за изпълнение на работен поток не се дублират. Ако при първоначалния работен поток е имало текущо изпълнение на друг работен поток, разклонението не получава негово копие.
- Разклонението е моментна снимка на текущото състояние. Текущите задачи на първоначалния работен поток не се дублират.
