GS2-Lock SDK for Game Engine API 레퍼런스
모델
EzMutex
뮤텍스
GS2가 제공하는 뮤텍스는 재진입 가능한 락의 일종입니다.
잠금을 획득할 때 트랜잭션 ID를 지정하며, 동일한 트랜잭션 ID를 지정한 경우에만 다시 잠금을 획득할 수 있습니다.
참조 카운터를 가지므로, 해제할 때에는 동일한 횟수만큼 잠금 해제 처리가 필요합니다.
뮤텍스는 네임스페이스·사용자 ID·프로퍼티 ID의 조합으로 식별됩니다.propertyId 에는 보호하려는 리소스를 고유하게 식별하는 임의의 문자열을 지정하며, 동시에 실행되면 안 되는 처리가 동일한 프로퍼티 ID에 대해 잠금을 획득합니다.
다른 트랜잭션 ID를 지정한 잠금 요청은 잠금이 유지되는 동안 거부되므로, 호출 측은 보유자가 해제할 때까지 기다렸다가 재시도합니다.referenceCount 는 최초 획득 시 1이 되며, 재진입할 때마다 증가하고 잠금 해제할 때마다 감소하여, 0이 되는 시점에 잠금이 완전히 해제됩니다.
잠금을 획득할 때에는 ttl 을 초 단위로 지정하며, 해당 기간이 경과하면 잠금은 자동으로 해제됩니다.
이를 통해 잠금을 보유한 채 처리가 중단된 경우에도 뮤텍스가 영구히 잠긴 상태로 남는 것을 방지할 수 있습니다. 예기치 못한 실패로 잠금 해제 횟수가 맞지 않게 된 경우에는 뮤텍스를 직접 삭제할 수도 있습니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| mutexId | string | ※ | ~ 1024자 | 뮤텍스 GRN
※ 서버가 자동으로 설정 | ||
| propertyId | string | ✓ | ~ 1024자 | 프로퍼티 ID 잠금 대상 리소스를 식별하기 위한 ID로, 어떤 리소스에 대한 잠금인지를 결정합니다. 여러 처리가 동일한 리소스에 대한 배타적 접근을 필요로 하는 경우, 동일한 프로퍼티 ID를 지정해야 합니다. | ||
| transactionId | string | ✓ | ~ 256자 | 트랜잭션 ID 잠금을 획득하는 트랜잭션의 식별자입니다. 이 ID는 재진입 가능한 잠금을 구현하는 데 사용됩니다. 잠금 요청이 현재 잠금을 보유한 것과 동일한 트랜잭션 ID를 지정한 경우, 잠금은 재획득에 성공하며 참조 카운터가 증가합니다. 다른 트랜잭션 ID로의 잠금 요청은 잠금이 유지되는 동안 거부됩니다. | ||
| ttlAt | long | 현재 시각으로부터 1시간 후의 절대 시각 | 유효기간 일시 UNIX 시간·밀리초 |
메서드
get
뮤텍스 상태 조회
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| propertyId | string | ✓ | ~ 1024자 | 프로퍼티 ID 잠금 대상 리소스를 식별하기 위한 ID로, 어떤 리소스에 대한 잠금인지를 결정합니다. 여러 처리가 동일한 리소스에 대한 배타적 접근을 필요로 하는 경우, 동일한 프로퍼티 ID를 지정해야 합니다. | ||
| gameSession | GameSession | ✓ | GameSession |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzMutex | 뮤텍스 |
구현 예제
var domain = gs2.Lock.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Mutex(
propertyId: "property-0001"
);
var item = await domain.ModelAsync(); var domain = gs2.Lock.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Mutex(
propertyId: "property-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Lock->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Mutex(
"property-0001" // propertyId
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}값 변경 이벤트 핸들링
var domain = gs2.Lock.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Mutex(
propertyId: "property-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); var domain = gs2.Lock.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Mutex(
propertyId: "property-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); const auto Domain = Gs2->Lock->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Mutex(
"property-0001" // propertyId
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Lock::Model::FMutex> value) {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
Domain->Unsubscribe(CallbackId);이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
lock
잠금 획득
ttl로 지정한 초 동안 프로퍼티 ID의 리소스를 잠급니다.
잠금 시에는 트랜잭션 ID를 지정해야 합니다.
서로 다른 트랜잭션 ID로 동일한 프로퍼티 ID에 대한 잠금 획득을 시도하면 실패합니다.
동일한 트랜잭션으로부터의 잠금 획득 요청인 경우에는 참조 카운터를 증가시킵니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| propertyId | string | ✓ | ~ 1024자 | 프로퍼티 ID 잠금 대상 리소스를 식별하기 위한 ID로, 어떤 리소스에 대한 잠금인지를 결정합니다. 여러 처리가 동일한 리소스에 대한 배타적 접근을 필요로 하는 경우, 동일한 프로퍼티 ID를 지정해야 합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| transactionId | string | ✓ | ~ 256자 | 트랜잭션 ID 잠금을 획득하는 트랜잭션의 식별자입니다. 이 ID는 재진입 가능한 잠금을 구현하는 데 사용됩니다. 잠금 요청이 현재 잠금을 보유한 것과 동일한 트랜잭션 ID를 지정한 경우, 잠금은 재획득에 성공하며 참조 카운터가 증가합니다. 다른 트랜잭션 ID로의 잠금 요청은 잠금이 유지되는 동안 거부됩니다. | ||
| ttl | long | ✓ | 0 ~ 9223372036854775805 | 잠금 획득 기간(초) |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzMutex | 뮤텍스 |
구현 예제
var domain = gs2.Lock.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Mutex(
propertyId: "property-0001"
);
var result = await domain.LockAsync(
transactionId: "transaction-0001",
ttl: 100000L
);
var item = await result.ModelAsync(); var domain = gs2.Lock.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Mutex(
propertyId: "property-0001"
);
var future = domain.LockFuture(
transactionId: "transaction-0001",
ttl: 100000L
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
}
var future2 = future.Result.ModelFuture();
yield return future2;
if (future2.Error != null)
{
onError.Invoke(future2.Error, null);
yield break;
}
var result = future2.Result; const auto Domain = Gs2->Lock->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Mutex(
"property-0001" // propertyId
);
const auto Future = Domain->Lock(
"transaction-0001", // transactionId
100000L // ttl
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}
// 변경된 값 / 결과 값을 취득
const auto Future2 = Future->GetTask().Result()->Model();
Future2->StartSynchronousTask();
if (Future2->GetTask().IsError())
{
return Future2->GetTask().Error();
}
const auto Result = Future2->GetTask().Result();unlock
잠금 해제
잠금을 해제하려면 동일한 트랜잭션 ID로부터 해제해야 합니다.
잠금 획득 시 재진입이 이루어진 경우에는 동일한 횟수만큼 잠금 해제를 수행해야 하며, 참조 카운터가 0이 되는 시점에 실제로 해제가 이루어집니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| propertyId | string | ✓ | ~ 1024자 | 프로퍼티 ID 잠금 대상 리소스를 식별하기 위한 ID로, 어떤 리소스에 대한 잠금인지를 결정합니다. 여러 처리가 동일한 리소스에 대한 배타적 접근을 필요로 하는 경우, 동일한 프로퍼티 ID를 지정해야 합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| transactionId | string | ✓ | ~ 256자 | 트랜잭션 ID 잠금을 획득하는 트랜잭션의 식별자입니다. 이 ID는 재진입 가능한 잠금을 구현하는 데 사용됩니다. 잠금 요청이 현재 잠금을 보유한 것과 동일한 트랜잭션 ID를 지정한 경우, 잠금은 재획득에 성공하며 참조 카운터가 증가합니다. 다른 트랜잭션 ID로의 잠금 요청은 잠금이 유지되는 동안 거부됩니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzMutex | 뮤텍스 |
구현 예제
var domain = gs2.Lock.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Mutex(
propertyId: "property-0001"
);
var result = await domain.UnlockAsync(
transactionId: "transaction-0001"
); var domain = gs2.Lock.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Mutex(
propertyId: "property-0001"
);
var future = domain.UnlockFuture(
transactionId: "transaction-0001"
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
} const auto Domain = Gs2->Lock->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Mutex(
"property-0001" // propertyId
);
const auto Future = Domain->Unlock(
"transaction-0001" // transactionId
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}
const auto Result = Future->GetTask().Result();