
# 시작하기

## 설치

### 요구 사항

- PHP 8.2 이상 및 WordPress 6.4 이상
- MySQL 8.0+ 또는 MariaDB 10.6+. 워커는 `SELECT ... FOR UPDATE SKIP LOCKED`로 작업과 실행 시각이 된 일정을 확보합니다. 이전 서버에서는 구문 오류가 발생합니다.
- `mysqli` 또는 `pdo_mysql`(아래 참조)
- `wp queuety work`으로 전용 워커를 실행하는 경우 서버에 WP-CLI 필요
- `--workers` 또는 `--min-workers`/`--max-workers`로 워커 풀을 실행하는 경우 `pcntl` 및 `posix` PHP 확장 필요

Queuety을 사용하려면 WordPress 및 WP-CLI을 로드하는 PHP 런타임에 `mysqli` 또는 `pdo_mysql`가 필요합니다. 드라이버는 자동으로 선택하며, WordPress 런타임에서는 `mysqli`을 우선하고 단독/직접 런타임 사용 시에는 `pdo_mysql`을 사용할 수 있도록 유지합니다.

WordPress 플러그인 계층 없이 DB 기반 런타임을 사용하려면 [독립 실행](https://queuety.inline0.dev/ko/docs/features/standalone-use)을 참조하세요. 이 방식은 같은 연결과 런타임 테이블을 사용하지만 WordPress 훅 브리지나 WP-CLI 등록은 포함하지 않습니다.

### 릴리스 zip에서 설치

모든 [GitHub 릴리스](https://github.com/inline0/queuety/releases)에는 `queuety.zip` 에셋이 있습니다. 플러그인과 Composer 종속 항목이 이미 설치되어 있습니다. WP-CLI를 사용해 최신 버전을 설치하세요:

```bash
wp plugin install https://github.com/inline0/queuety/releases/latest/download/queuety.zip --activate
```

또는 zip 파일을 다운로드해 플러그인 > 새 플러그인 추가 > 플러그인 업로드에서 업로드하세요. 일반 WordPress 사이트에는 이 방법이 가장 간단합니다.

### Composer을 통해 Composer 관리형 WordPress에 설치

```bash
composer require queuety/queuety
```

그런 다음 플러그인을 활성화하세요.

```bash
wp plugin activate queuety
```

패키지 유형은 `wordpress-plugin`입니다. Composer은 프로젝트에서 `composer/installers`가 필요하고 해당 유형을 설치 프로그램 경로에 매핑하는 경우에만 플러그인 디렉터리에 설치합니다. Bedrock이 그렇게 하며, 프로젝트는 자체 `vendor/autoload.php`를 로드해야 합니다(Bedrock도 그렇게 합니다). `composer/installers`이 없으면 Composer은 패키지를 `vendor/queuety/queuety`에 설치하는데, WordPress은 여기서 패키지를 찾지 못합니다. 따라서 일반 WordPress 설치에서는 릴리스 zip을 사용하세요.

### 개발 중 소스에서 설치

저장소를 `wp-content/plugins/queuety`에 배치한 다음 PHP 종속 항목을 설치하세요:

```bash
composer install
wp plugin activate queuety
```

활성화하면 Queuety은 데이터베이스 테이블(`queuety_jobs`, `queuety_workflows`, `queuety_logs`, `queuety_schedules`, `queuety_queue_states`, `queuety_webhooks`, `queuety_locks`, `queuety_signals`, `queuety_workflow_dependencies`, `queuety_workflow_dispatch_keys`, `queuety_batches`, `queuety_chunks`, `queuety_workflow_events`, `queuety_artifacts`, `queuety_state_machines`, `queuety_state_machine_events`)을 생성하므로 워커가 MySQL에서 직접 작업을 가져올 수 있습니다.

기본적으로 플러그인은 `default` 큐를 위해 WordPress cron을 통해 매분 한 번 실행되는 일회성 워커도 예약합니다. WordPress cron이 실행되기만 하면 `default`에서 진행되는 작업과 워크플로우를 위한 셸 없는 기본 실행 방식으로 사용할 수 있습니다. 각 실행은 최대 하나의 작업만 처리하며, 반복 예약을 실행하거나 오래된 작업을 복구하거나 워크플로우 마감 시간을 확인하지 않습니다. 이러한 작업은 장시간 실행되는 `wp queuety work` 프로세스([#14](https://github.com/inline0/queuety/issues/14)) 안에서만 수행됩니다. 사용자 지정 큐, 반복 예약, 짧은 지연 시간 또는 더 많은 작업량이 필요하면 전용 `wp queuety work` 프로세스로 전환하세요.

## 구성

모든 상수는 선택 사항입니다. 플러그인이 로드되기 전에 또는 테마 스타일의 임베디드 설치에서 Queuety이 부팅되기 전에 `wp-config.php`에서 정의하세요:

| 상수 | 기본값 | 설명 |
|---|---|---|
| `QUEUETY_RETENTION_DAYS` | `7` | `wp queuety purge` 및 `Queuety::purge()`의 기본 보관 기간(일). 자동 삭제는 수행되지 않음 |
| `QUEUETY_LOG_RETENTION_DAYS` | `0` | `Config::log_retention_days()`에서 읽지만 아직 사용하지 않음. `Queuety::purge_logs()`([#15](https://github.com/inline0/queuety/issues/15))을 호출할 때까지 로그가 보관됨 |
| `QUEUETY_MAX_EXECUTION_TIME` | `300` | 시간 초과 전 작업당 최대 초(아직 적용되지 않음. [작업](https://queuety.inline0.dev/ko/docs/jobs#timeout) 참고) |
| `QUEUETY_WORKER_SLEEP` | `1` | 큐가 비었을 때 대기할 시간(초) |
| `QUEUETY_WORKER_MAX_JOBS` | `1000` | 워커가 재시작하기 전 최대 작업 수 |
| `QUEUETY_WORKER_MAX_MEMORY` | `128` | 워커가 재시작하기 전 최대 메모리(MB) |
| `QUEUETY_RETRY_BACKOFF` | `exponential` | 백오프 전략: `exponential`, `linear` 또는 `fixed` |
| `QUEUETY_STALE_TIMEOUT` | `600` | 멈춘 작업을 복구하기 전 대기 시간(초) |
| `QUEUETY_CACHE_TTL` | `5` | 기본 캐시 TTL(초) |
| `QUEUETY_DEBUG` | `false` | 상세 워커 로깅 사용 설정 |
| `QUEUETY_CLI_COMMAND` | `queuety` | 루트 WP-CLI 명령 이름 |
| `QUEUETY_TABLE_PREFIX` | `queuety_` | WordPress DB 접두사 뒤에 오는 모든 Queuety 테이블의 공통 기본 이름 |
| `QUEUETY_TABLE_JOBS` | `queuety_jobs` | 작업 테이블 이름 |
| `QUEUETY_TABLE_WORKFLOWS` | `queuety_workflows` | 워크플로우 테이블 이름 |
| `QUEUETY_TABLE_LOGS` | `queuety_logs` | 로그 테이블 이름 |
| `QUEUETY_TABLE_SCHEDULES` | `queuety_schedules` | 예약 테이블 이름 |
| `QUEUETY_TABLE_SIGNALS` | `queuety_signals` | 신호 테이블 이름 |
| `QUEUETY_TABLE_WORKFLOW_DEPENDENCIES` | `queuety_workflow_dependencies` | 워크플로우 종속성 대기 테이블 이름 |
| `QUEUETY_TABLE_WORKFLOW_DISPATCH_KEYS` | `queuety_workflow_dispatch_keys` | 내구성 있는 워크플로우 멱등성 테이블 이름 |
| `QUEUETY_TABLE_CHUNKS` | `queuety_chunks` | 스트리밍 청크 테이블 이름 |
| `QUEUETY_TABLE_QUEUE_STATES` | `queuety_queue_states` | 큐 상태 테이블 이름 |
| `QUEUETY_TABLE_WEBHOOKS` | `queuety_webhooks` | 웹훅 테이블 이름 |
| `QUEUETY_TABLE_LOCKS` | `queuety_locks` | 잠금 테이블 이름 |
| `QUEUETY_TABLE_BATCHES` | `queuety_batches` | 배치 테이블 이름 |
| `QUEUETY_TABLE_WORKFLOW_EVENTS` | `queuety_workflow_events` | 워크플로우 이벤트 로그 테이블 이름 |
| `QUEUETY_TABLE_ARTIFACTS` | `queuety_artifacts` | 워크플로우 아티팩트 테이블 이름 |
| `QUEUETY_TABLE_STATE_MACHINES` | `queuety_state_machines` | 상태 머신 테이블 이름 |
| `QUEUETY_TABLE_STATE_MACHINE_EVENTS` | `queuety_state_machine_events` | 상태 머신 이벤트 로그 테이블 이름 |
| `QUEUETY_DB_DRIVER` | `auto` | MySQL 드라이버: `auto`, `mysqli` 또는 `pdo`. `auto`은 WordPress이 로드된 경우 `mysqli`을 우선 사용하고, 그렇지 않으면 `pdo_mysql`을 사용한 다음 `mysqli`을 사용함 |

리소스 승인 및 적응형 풀 상수(`QUEUETY_RESOURCE_*`, `QUEUETY_WORKER_POOL_*`)는 [워커](https://queuety.inline0.dev/ko/docs/features/workers) 페이지에 나와 있습니다.

`QUEUETY_TABLE_PREFIX`은 테이블 이름에서 Queuety 부분만 변경합니다. WordPress 데이터베이스 접두사는 결과에 계속 적용되므로 `$wpdb->prefix = 'wp_'` 및 `QUEUETY_TABLE_PREFIX = 'themequeue_'`는 `wp_themequeue_jobs`와 같은 테이블 이름을 만듭니다. 개별 테이블에 지정한 `QUEUETY_TABLE_*` 상수가 우선 적용됩니다.

독립 실행형 연결은 연결별로 Queuety 테이블 접두사를 설정할 수도 있습니다:

```php
$conn = new Connection(
    host: '127.0.0.1:3306',
    dbname: 'wordpress',
    user: 'root',
    password: 'secret',
    prefix: 'wp_',
    table_prefix: 'themequeue_',
);
```

이렇게 하면 WordPress 데이터베이스 접두사는 그대로 유지하고 Queuety 테이블 부분만 변경합니다.

## 첫 작업 만들기

`Handler` 인터페이스를 구현하는 핸들러 클래스를 만드세요:

```php
use Queuety\Handler;

class SendEmailHandler implements Handler {
    public function handle( array $payload ): void {
        wp_mail( $payload['to'], $payload['subject'], $payload['body'] );
    }

    public function config(): array {
        return [
            'queue'           => 'emails',
            'max_attempts'    => 5,
        ];
    }
}
```

등록한 다음 디스패치하세요:

```php
use Queuety\Queuety;

Queuety::register( 'send_email', SendEmailHandler::class );

Queuety::dispatch( 'send_email', [
    'to'      => 'user@example.com',
    'subject' => 'Welcome',
    'body'    => 'Hello from Queuety!',
] );
```

또는 최신 디스패치 가능 작업 클래스를 사용하세요:

```php
use Queuety\Contracts\Job;
use Queuety\Dispatchable;

readonly class SendEmailJob implements Job {
    use Dispatchable;

    public function __construct(
        public string $to,
        public string $subject,
        public string $body,
    ) {}

    public function handle(): void {
        wp_mail( $this->to, $this->subject, $this->body );
    }
}

SendEmailJob::dispatch( 'user@example.com', 'Welcome', 'Hello from Queuety!' );
```

## 첫 워크플로우 만들기

`Step` 인터페이스를 구현하는 단계 핸들러를 정의하세요:

```php
use Queuety\Step;

class FetchDataHandler implements Step {
    public function handle( array $state ): array {
        $user = get_user_by( 'ID', $state['user_id'] );
        return [ 'user_name' => $user->display_name ];
    }

    public function config(): array {
        return [];
    }
}

class CallLLMHandler implements Step {
    public function handle( array $state ): array {
        $response = wp_remote_post( 'https://api.openai.com/v1/chat/completions', [
            'body' => json_encode( [ 'prompt' => "Generate report for {$state['user_name']}" ] ),
        ] );
        return [ 'llm_response' => wp_remote_retrieve_body( $response ) ];
    }

    public function config(): array {
        return [ 'max_attempts' => 5 ];
    }
}

class FormatOutputHandler implements Step {
    public function handle( array $state ): array {
        $url = save_report( $state['user_name'], $state['llm_response'] );
        return [ 'report_url' => $url ];
    }

    public function config(): array {
        return [];
    }
}
```

워크플로우를 디스패치하세요:

```php
$workflow_id = Queuety::workflow( 'generate_report' )
    ->then( FetchDataHandler::class )
    ->then( CallLLMHandler::class )
    ->then( FormatOutputHandler::class )
    ->dispatch( [ 'user_id' => 42 ] );
```

## 워커 시작

```bash
wp queuety work
```

워커는 대기 중인 작업을 폴링하고 실행하며 워크플로우를 진행하고 큐가 비면 대기합니다. 중지하려면 `Ctrl+C`을 누르세요. 작업 중간이라도 프로세스가 즉시 종료됩니다([워커](https://queuety.inline0.dev/ko/docs/features/workers#worker-lifecycle) 참고).

위의 `SendEmailHandler`은 `config()`을 통해 작업을 `emails` 큐로 보내므로 `default`에서 실행되는 워커는 해당 작업을 가져오지 않습니다. 사용하는 모든 큐의 이름을 지정하세요:

```bash
wp queuety work --queue=emails,default
```

전용 워커를 실행하지 않아도 Queuety에는 위에서 설명한 기본 분당 1회 WordPress cron 대체 실행 방식이 있습니다. 이는 `default` 큐로 제한되며 실행당 작업 하나만 처리합니다. 전용 워커는 처리량이 더 많고 지연 시간이 더 짧은 선택지입니다.

프로덕션 환경에서는 워커를 여러 개 실행하세요:

```bash
wp queuety work --workers=4
```

우선순위 순서에 따라 여러 큐를 처리하세요:

```bash
wp queuety work --queue=high,default,low
```

## 다음 단계

- [작업](https://queuety.inline0.dev/ko/docs/jobs): 전체 디스패치 및 핸들러 가이드
- [워크플로](https://queuety.inline0.dev/ko/docs/workflows): 체인, 병렬 단계, 조건부 분기 및 워크플로 실행
- [미들웨어](https://queuety.inline0.dev/ko/docs/features/middleware): 속도 제한, 스로틀링 및 사용자 지정 파이프라인 로직
- [일괄 처리](https://queuety.inline0.dev/ko/docs/features/batching): 콜백을 사용한 작업 그룹 디스패치
- [스트리밍 단계](https://queuety.inline0.dev/ko/docs/workflows/streaming): 스트리밍 데이터를 청크 단위로 저장
- [예약](https://queuety.inline0.dev/ko/docs/features/scheduling): 반복 작업
- [캐싱](https://queuety.inline0.dev/ko/docs/features/caching): 플러그형 캐시 계층
- [테스트](https://queuety.inline0.dev/ko/docs/features/testing): QueueFake 및 테스트 어설션
- [CLI 참조](https://queuety.inline0.dev/ko/docs/cli): 사용 가능한 모든 명령
- [PHP API](https://queuety.inline0.dev/ko/docs/api): 프로그래밍 방식 액세스
