> Discover all available pages from the documentation index: https://mastra.zisheng.pro/ko/llms.txt # 임대 공급자 `LeaseProvider`이벤트 전달과 별도로 분산 임대 계약입니다([`PubSub`](https://mastra.zisheng.pro/ko/reference/pubsub/base)). 마스트라의[신호 레이어](https://mastra.zisheng.pro/ko/docs/long-running-agents/signals)이를 사용하여 여러 프로세스(예: 서버리스 호출)에서 리소스(가장 일반적으로 스레드 키)에 대한 단일 소유자를 선택합니다. 소유자는 Agent 스트림을 깨우고 실행하는 프로세스이므로 다른 프로세스는 경쟁 실행을 시작하는 대신 후속 작업을 여기에 라우팅합니다. 임대는 pub/sub와 별개의 문제입니다. 백엔드는 원자적 `SET`/Lua를 사용하는 Redis나 단일 프로세스용 Memory 맵처럼 실제로 잠금을 조정할 수 있을 때만 `LeaseProvider`를 구현합니다. 임대를 지원하지 않는 백엔드는 이를 생략합니다. 신호 런타임은 기능을 감지하고 아무 작업도 하지 않는 Provider로 대체하여 단일 프로세스 동작을 보존합니다. 내장 [`RedisStreamsPubSub`](https://mastra.zisheng.pro/ko/reference/pubsub/redis-streams)은 `LeaseProvider`를 구현하며, 이를 통해 신호가 분산 및 서버리스 배포에서 인스턴스 간 조정을 수행할 수 있습니다. ## 사용예 `LeaseProvider`를 직접 생성하지 않습니다. 이를 구현하는 pub/sub 백엔드(예: `RedisStreamsPubSub`)를 `Mastra` 생성자에 구성하면 신호 런타임이 프로세스 간 조정에 자동으로 사용합니다. ```typescript import { Mastra } from '@mastra/core' import { RedisStreamsPubSub } from '@mastra/redis-streams' export const mastra = new Mastra({ // RedisStreamsPubSub implements both PubSub and LeaseProvider pubsub: new RedisStreamsPubSub({ url: process.env.REDIS_URL, }), }) ``` 커스텀 백엔드에서 임대를 구현하려면 아래 메서드를 구현하세요. 신호 런타임은 기능을 구조적으로 감지하여(패키지 경계를 넘어 작동함) 모든 메소드가 존재할 때만 이를 사용합니다. ```typescript import { PubSub } from '@mastra/core/events' import type { LeaseProvider } from '@mastra/core/events' export class CustomPubSub extends PubSub implements LeaseProvider { async acquireLease(key: string, owner: string, ttlMs: number) { // Atomically claim the lease, or report the current holder. return { acquired: true, owner } } // ...getLeaseOwner, releaseLease, renewLease, transferLease } ``` ## 행동 양식 ### 임대 #### `acquireLease(key, owner, ttlMs)` 키의 임대를 원자적으로 획득하려고 시도합니다. 호출자가 임대를 확보하면 `{ acquired: true, owner }`를 반환하고, 그렇지 않으면 현재 보유자가 `owner`인 `{ acquired: false, owner }`를 반환하여 호출자가 후속 작업을 해당 보유자에게 라우팅할 수 있게 합니다. 동일한 소유자는 `acquireLease`를 멱등적으로 호출하여 갱신하거나 다시 확보할 수 있습니다. ```typescript const result = await pubsub.acquireLease('thread:abc', runId, 15000) if (result.acquired) { // This process owns the thread, so wake and run the agent. } else { // result.owner holds the lease, so route the signal to them. } ``` 보고:`Promise<{ acquired: boolean; owner?: string }>` **key** (`string`): 스레드 키와 같은 임대 키입니다. **owner** (`string`): runId와 같은 소유자 식별자입니다. 동일한 소유자는 acquireLease를 멱등적으로 호출하여 갱신하거나 해제할 수 있습니다. **ttlMs** (`number`): 임대의 밀리초 단위 유효 시간입니다. #### `getLeaseOwner(key)` 현재 임대 소유자를 읽으며, 유지 중인 임대가 없으면 `undefined`를 반환합니다. ```typescript const owner = await pubsub.getLeaseOwner('thread:abc') ``` 보고:`Promise` #### `releaseLease(key, owner)` 임대를 해제합니다. 호출자가 현재 소유자가 아닌 경우에는 아무 작업도 수행할 수 없습니다. 구현은 해제하기 전에 원자적으로 소유권을 확인하므로 다른 소유자에 의한 동시 갱신이 방해받지 않습니다. ```typescript await pubsub.releaseLease('thread:abc', runId) ``` 보고:`Promise` #### `renewLease(key, owner, ttlMs)` `owner`가 소유한 기존 임대를 갱신하여 TTL을 연장합니다. 갱신에 성공하고 호출자가 여전히 임대를 소유하면 `true`를, 임대를 잃었으면(TTL이 만료되었거나 다른 소유자가 확보한 경우) `false`를 반환합니다. ```typescript const stillOwned = await pubsub.renewLease('thread:abc', runId, 15000) if (!stillOwned) { // Lost the lease, so stop renewing and let the new owner take over. } ``` 보고:`Promise` #### `transferLease(key, fromOwner, toOwner, ttlMs)` 보유한 임대를 `fromOwner`에서 `toOwner`로 원자적으로 이전하고 중간에 키를 해제하지 않은 채 TTL을 갱신합니다. 이 공백 없는 기본 연산을 사용하면 현재 소유자가 완료한 직후 후속 소유자가 동일한 키를 넘겨받을 수 있습니다. 예를 들어 대기 중인 후속 실행은 스레드 실행이 완료될 때 이를 넘겨받을 수 있습니다. 단순히 해제한 후 획득하면 잠시 키가 비게 됩니다. 이때 경합 중인 프로세스가 해제된 임대를 먼저 확보하고 경쟁 실행을 시작할 수 있습니다. `fromOwner`가 여전히 임대를 보유하여 소유권이 `toOwner`로 이전되었으면 `true`를 반환하고, 임대를 이미 잃었으면 `false`를 반환합니다. 후자의 경우 호출자는 새 `acquireLease` 호출로 대체해야 합니다. ```typescript const transferred = await pubsub.transferLease('thread:abc', currentRunId, nextRunId, 15000) if (!transferred) { // Lease was lost, so acquire fresh instead. await pubsub.acquireLease('thread:abc', nextRunId, 15000) } ``` 보고:`Promise` > **경고:** 원자적으로 이전할 수 없는 백엔드는 `releaseLease(fromOwner)`를 호출한 후 `acquireLease(toOwner)`를 호출하는 최선형 방식으로 이전을 구현해야 하며, 그 사이에 경합 중인 프로세스가 키를 확보할 수 있으므로 교환이 비원자적임을 문서화해야 합니다. 메서드를 필수로 유지하면 호출자가 단일 코드 경로를 사용할 수 있고 원자성은 백엔드별로 명시적으로 결정됩니다. ## 능력 탐지 신호 런타임은 `instanceof` 대신 구조적으로 `LeaseProvider`를 감지하므로 별도로 게시된 백엔드가 다른 `@mastra/core` 사본을 해석하더라도 감지가 작동합니다. 다섯 메서드(`acquireLease`, `getLeaseOwner`, `releaseLease`, `renewLease`, `transferLease`)를 모두 노출하는 값은 `LeaseProvider`로 처리됩니다. 구성된 Pub/Sub 백엔드가 `LeaseProvider`를 구현하지 않으면 런타임은 항상 성공하는 무작동 Provider로 대체합니다. 모든 호출자가 자체 임대 경쟁에서 이기며 해제, 갱신, 이전은 아무 효과가 없습니다. 이를 통해 예상되는 단일 프로세스 동작이 유지됩니다. ## 관련된 - [PubSub](https://mastra.zisheng.pro/ko/reference/pubsub/base): 임대와는 별도로 이벤트 배송 계약 - [RedisStreamsPubSub](https://mastra.zisheng.pro/ko/reference/pubsub/redis-streams): 구현하는 내장 백엔드`LeaseProvider` - [신호](https://mastra.zisheng.pro/ko/docs/long-running-agents/signals): 프로세스 전반에 걸쳐 스레드 실행을 조정하기 위해 임대를 사용하는 런타임 - [채널](https://mastra.zisheng.pro/ko/docs/capabilities/channels/overview): 임대를 사용하여 서버리스 및 다중 인스턴스 배포에서 Agent 실행을 조정합니다.