소개
Queuety은 빠른 작업 큐, 내구성 있는 워크플로우 엔진 및 내구성 있는 상태 머신 런타임을 제공하는 WordPress 플러그인입니다. 워커는 MySQL에서 직접 작업을 가져와 장시간 실행되는 WP-CLI 프로세스 안에서 처리합니다. WordPress 및 WP-CLI을 로드하는 PHP 런타임에는 mysqli 또는 pdo_mysql이 필요합니다.
Queuety을 사용하는 이유는 무엇인가요?
WordPress에는 실제 백그라운드 작업 시스템이 없습니다. wp_cron은 페이지 방문 시에만 실행됩니다. Action Scheduler의 기본 실행기는 WP-Cron 및 루프백 HTTP 요청을 이용하며, 각 요청은 최대 30초 동안 배치를 처리합니다. 60초가 걸리는 LLM API 호출은 PHP의 30초 시간 초과로 종료됩니다. 충돌 후에도 살아남아 중단 지점에서 재개하는 다단계 프로세스를 실행할 방법이 없습니다.
Queuety은 세 가지 기본 요소로 이 문제를 해결합니다:
- 작업은 실행 후 잊어도 되는 백그라운드 작업에 사용합니다.
- 워크플로우는 상태를 유지하는 내구성 있는 다단계 프로세스에 사용합니다.
- 상태 머신은 오래 지속되는 이벤트 기반 수명 주기 상태를 모델링합니다.
빠른 예제
최신 API을 사용해 작업을 디스패치하세요:
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!' );
또는 기존 핸들러 이름 방식을 사용하세요:
use Queuety\Queuety;
Queuety::dispatch( 'send_email', [ 'to' => 'user@example.com' ] );
내구성 있는 워크플로우를 실행하세요:
Queuety::workflow( 'generate_report' )
->then( FetchDataHandler::class )
->then( CallLLMHandler::class )
->then( FormatOutputHandler::class )
->dispatch( [ 'user_id' => 42 ] );
상태 머신으로 오래 지속되는 세션을 모델링하세요:
use Queuety\Enums\StateMachineStatus;
Queuety::machine( 'agent_session' )
->state( 'awaiting_user' )
->on( 'user_message', 'planning' )
->state( 'planning' )
->action( PlanSessionAction::class )
->on( 'planned', 'completed' )
->state( 'completed', StateMachineStatus::Completed )
->dispatch( [ 'thread_id' => 42 ] );
워커를 시작하세요:
wp queuety work
에이전트 스타일 시스템을 구축한다면 에이전트 오케스트레이션부터 시작하세요. 플래너/실행기 흐름, 사람의 검토 단계, 워크플로우 간 대기가 어떻게 함께 작동하는지 설명합니다.
시스템이 이벤트 기반이고 오래 지속된다면 워크플로우와 함께 상태 머신부터 살펴보세요.
엔드투엔드 통합 예제가 필요하면 예제를 확인하세요. 여기에는 제공자 전환, 스트리밍, 메모리 기반 검토 반복 및 종속 워크플로우를 위한 Neuron 기반 패턴이 포함되어 있습니다.
WordPress 같은 save_post 도메인 이벤트에서 워크플로우를 시작하려면 액션 트리거를 확인하세요.
DB 기반 런타임을 WordPress 외부에서 사용하려면 독립 실행형 사용을 확인하세요.
주요 차별점
- 빠른 실행. 워커는 직접 MySQL 큐에 액세스하므로 WordPress의 백그라운드 작업을 느리게 만드는 요청별 cron 패턴을 피합니다.
- 내구성 있는 워크플로우. 지속 상태를 사용하는 다단계 프로세스는 PHP 시간 초과, 충돌 및 재시도에도 유지됩니다. 각 단계 경계는 원자적 MySQL 트랜잭션입니다.
- 명시적 상태 머신. 이름이 지정된 상태, 가드가 있는 전환, 큐에 등록되는 상태 진입 작업, 내구성 있는 이벤트 타임라인으로 채팅 세션, 승인 및 기타 장기 수명 주기를 모델링합니다.
- 최신 디스패치 API.
Dispatchable트레이트, 페이로드 역할을 하는 타입 지정 생성자 속성, 클래스에 선언된$tries/$timeout/$backoff을 사용하는 독립형 작업 클래스입니다.readonly클래스에서는 이러한 속성에 기본값을 지정할 수 없으므로 readonly 승격 생성자 속성을 사용하는 일반 클래스에 선언하세요. - 미들웨어 파이프라인. 속도 제한, 예외 스로틀링, 고유 작업 및 사용자 지정 로직을 위한 양파형 미들웨어입니다. 작업별
middleware()메서드로 선언합니다. - 스트리밍 단계.
StreamingStep인터페이스는 청크를 생성해 데이터베이스에 즉시 저장합니다. 재시도 시 이전에 저장된 청크가 전달되므로 스트림을 중단된 지점부터 재개할 수 있습니다. LLM 응답 및 대용량 다운로드에 적합합니다. - 플러그형 캐시 계층.
CacheFactory은 APCu를 자동 감지하고, 사용할 수 없으면 메모리 내 캐시로 대체합니다. 사용자 지정 백엔드는Contracts\Cache를 구현합니다. 속도 제한 조회 및 큐 상태에 내부적으로 사용됩니다. - 배칭 및 체이닝.
then/catch/finally콜백과 진행률 추적을 사용해 작업 그룹을 디스패치하거나, 앞 작업이 완료되어야 다음 작업이 진행되는 순차 작업 체인을 구성합니다. - 내구성 있는 지연 및 대기.
delay()은 프로세스가 재시작되어도 유지되는 지연을 추가합니다.wait_for_signal(),wait_for_signals(),wait_for_approval(),wait_for_input()및wait_for_workflow()을 사용하면 PHP을 계속 실행하지 않고도 외부 이벤트나 다른 워크플로우를 기다리도록 워크플로우를 일시 중지할 수 있습니다. - 동적 for-each.
for_each()는 워크플로우 상태에서 런타임에 검색된 분기 작업을 확장하고 전체 성공, 첫 성공 및 정족수 완료 모드를 지원합니다. - 비동기 워크플로우 핸드오프.
start_workflows()은 런타임에 검색된 항목을 나중에 기다릴 수 있는 독립적인 최상위 워크플로우로 전환합니다. - WordPress 액션 트리거.
on_action()은 코어 또는 플러그인 액션 훅을 게이팅 및 멱등성을 갖춘 내구성 있는 워크플로우 디스패치에 연결합니다. - 내구성 있는 아티팩트. 이름이 지정된 워크플로우 출력을 기본 상태 저장소 외부에 저장하고 상태, CLI 검사, 내보내기 및 재생 과정에서 유지합니다.
- 워크플로우 가드레일.
version(), 결정적 정의 해시, 멱등성 디스패치 키 및 워크플로우 예산을 통해 에이전트 스타일 실행을 더 쉽게 검사하고 중복 실행이나 제어되지 않는 실행을 방지합니다. - 리소스 관리. 동시성 그룹, 비용 단위, 워크플로우 예산 및 워커 승인으로 비용이 큰 에이전트 스타일 작업을 정해진 한도 안에서 실행하도록 합니다.
- 단계 보상.
compensate_with()및compensate_on_failure()는 워크플로우가 취소되거나 실패할 때 완료된 단계를 롤백하는 훅을 제공합니다. - 하트비트. 장시간 실행되는 단계는 하트비트를 전송해 오래된 작업 복구 시스템이 활성 작업을 회수하지 못하게 합니다.
- 워크플로우 추적. 모든 단계 전환은 입력, 출력, 전후 상태, 컨텍스트, 아티팩트, 청크, 오류와 함께 기록되며
workflow_state_at()을 사용한 시간 여행 디버깅도 지원합니다. - 병렬 단계. 여러 단계를 동시에 실행하고 모두 완료될 때까지 기다린 후 다음 단계로 진행합니다.
- 조건부 분기.
_next_step을 사용해 이전 상태에 따라 이름이 지정된 단계로 건너뜁니다. - 워크플로우 실행. 결과를 부모에게 반환하는 자식 워크플로우를 시작합니다.
- 우선순위 큐. 타입 안전 PHP 열거형을 통해 낮음, 보통, 높음, 긴급의 네 가지 우선순위를 지원합니다.
- 다중 큐 워커. 하나의 워커에서 엄격한 우선순위 순서로 여러 큐를 처리합니다.
- 속도 제한. 슬라이딩 윈도우 방식으로 핸들러별 실행 횟수를 제한합니다.
- 반복 작업. 간격 기반 및 cron 기반 예약과 구성 가능한 중복 실행 정책(허용, 건너뛰기, 버퍼링)을 지원합니다.
- 워크플로우 취소. 실행 중인 워크플로우를 취소하고 등록된 정리 핸들러를 실행합니다.
- 상태 정리. 오래된 단계 출력을 자동으로 제거해 대형 워크플로우 상태를 관리하기 쉽게 유지합니다.
- 워커 동시성.
--workers=N는 여러 프로세스를 분기하고 충돌 시 자동으로 재시작합니다. - 완전한 관측성. 데이터베이스 로깅, 핸들러별 메트릭 및 이벤트 웹훅을 제공합니다.
- 테스트 유틸리티.
QueueFake는 단위 테스트에서 단언할 수 있도록 디스패치된 작업과 배치를 기록합니다. - PHP 속성.
#[QueuetyHandler('name')]을 사용해 설정 없이 핸들러를 등록합니다.
작동 방식
워커는 오래 실행되는 WP-CLI 프로세스 안에서 실행되며 MySQL에서 직접 작업을 가져옵니다. 큐 행, 워크플로우 상태, 로그, 배치, 신호 및 스트리밍 청크는 모두 MySQL에 저장되므로 워커가 재시작되어도 오케스트레이션 상태가 사라지지 않습니다.
워크플로우는 장시간 실행되는 작업을 단계로 나눕니다. 각 단계는 출력을 데이터베이스의 공유 상태 저장소에 유지합니다. PHP이 단계 실행 중 종료되면 워커는 이전 상태를 모두 보존한 채 해당 단계를 재시도합니다. 단계 경계는 하나의 MySQL 트랜잭션입니다. 상태 업데이트, 작업 완료 및 다음 단계 큐 등록이 모두 원자적으로 수행됩니다.
Workflow: generate_report (3 steps)
Step 0: fetch_data -> state: {user_data: {...}}
Step 1: call_llm -> PHP dies -> retry -> state: {user_data: {...}, llm_response: "..."}
Step 2: format_output -> state: {user_data: {...}, llm_response: "...", report_url: "/reports/42.pdf"}
Workflow: completed
요구 사항
- PHP 8.2 이상
- WordPress 6.4 이상
- MySQL 8.0+ 또는 MariaDB 10.6+ (워커가
SELECT ... FOR UPDATE SKIP LOCKED를 사용해 작업을 가져오기 때문) - WordPress 및 WP-CLI을 로드하는 PHP 런타임의
mysqli또는pdo_mysql wp queuety work로 전용 워커를 실행하기 위한 WP-CLI- 워커 풀을 위한
pcntl및posixPHP 확장(--workers,--min-workers,--max-workers)
설치는 시작하기를 참고하세요.