Documentation index for AI agents

GS2-Limit Transaction Actions

Specification of verify/consume/acquire transaction actions

Combining actions, and concurrency

The background common to every service is collected in Combining Transaction Actions. Read that first; the rest of this section is what GS2-Limit adds to it.

The transaction actions of GS2-Limit address one counter, identified by the combination of namespace, user, limit model, and counter name.

OperationRepeated in one transactionAcross a nested transactionBoundary that separates targets
Counting up and down
CountUpByUserId CountDownByUserId
Any mix; combined and the values added up. Count ups with differing maxValue are rejected when the transaction is issuedAdded upnamespace, user, limit model, counter name
Deleting a counter
DeleteCounterByUserId
CombinedFailsnamespace, user, limit model, counter name
Verifying
VerifyCounterByUserId
The thresholds are added up, so writing exactly the same check twice doubles it. Checks with differing counts are each judgedNo collision, because it only readscounter, verify type, count

Counting up and down are one row because both are written as a pure increment on the same value; mixing them is fine. The result is judged against the total after combining. The count cannot go below zero and cannot exceed the limit set on the limit model, so a count up that fits on its own can still be rejected when combined with another one.

Count ups with differing upper limits cannot be placed against the same counter. Adding them up while the limits disagree would either drop a stricter limit or have a permissive increment rejected by a stricter one, so count ups with differing maxValue against one counter are rejected when the transaction is issued. Specify them separately.

Deleting a counter removes the counter itself rather than changing its value, so it cannot sit alongside anything else on that counter. Split the transaction where you want to reset a counter and then start counting again.

Verify actions look at the counter as of the start of the transaction. You cannot verify a count that is reached by the same transaction.

Take care with nested transactions

Counting up and down are safe across a nested transaction: they are applied together as one update whichever route they arrive by.

Deleting a counter is not. A deletion arriving from the inside while the same counter is counted from the outside makes the transaction fail.

If you want to avoid these restrictions

Counting down and deleting a counter are acquire actions; counting up is a consume action. Turning acquireActionUseJobQueue on clears a collision between a deletion and a count down, but a deletion together with a count up needs enableAtomicCommit turned off.

Concurrency and retries

Counting up and down do not conflict however many concurrent requests overlap, as long as the result stays within range. A conflict (409) is returned when concurrent count ups together exceed the limit, or when concurrent count downs together take the count below zero; retrying re-evaluates against the latest count.

A counter is reset on a schedule. A request that lands exactly on a reset boundary may return a conflict (409); retrying after the reset has settled will succeed.


Verify Action

Gs2Limit:VerifyCounterByUserId

Verify Counter value by User ID

Verifies that the specified user’s counter value satisfies the given condition. Supports 6 comparison operators: less, lessEqual, greater, greaterEqual, equal, notEqual.

Quantity specification supported: NO

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
limitNamestring
~ 128 charsUsage Limit Model Name
The name of the limit model that this counter belongs to. Determines the reset schedule (daily, weekly, monthly, etc.) applied to this counter’s value.
counterNamestring
~ 128 charsCounter Name
A unique identifier for this counter within the limit model. Multiple counters can share the same limit model with different names, allowing separate usage tracking (e.g., one counter per quest or per product) without creating separate limit models.
verifyTypestring (enum)
enum {
  “less”,
  “lessEqual”,
  “greater”,
  “greaterEqual”,
  “equal”,
  “notEqual”
}
Type of verification
DefinitionDescription
lessPossession quantity is less than the specified value
lessEqualPossession quantity is less than or equal to the specified value
greaterPossession quantity is greater than the specified value
greaterEqualPossession quantity is greater than or equal to the specified value
equalPossession quantity is equal to the specified value
notEqualPossession quantity is not equal to the specified value
countint00 ~ 2147483646Count Value
The current usage count for this counter. Incremented by the countUp operation and compared against the maximum value specified at that time. Automatically reset to zero when the limit model’s reset timing is reached.
multiplyValueSpecifyingQuantitybooltrueWhether to multiply the value used for verification when specifying the quantity
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2Limit:VerifyCounterByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "userId": "[string]User ID",
        "limitName": "[string]Usage Limit Model Name",
        "counterName": "[string]Counter Name",
        "verifyType": "[string]Type of verification",
        "count": "[int]Count Value",
        "multiplyValueSpecifyingQuantity": "[bool]Whether to multiply the value used for verification when specifying the quantity",
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2Limit:VerifyCounterByUserId
request:
  namespaceName: "[string]Namespace name"
  userId: "[string]User ID"
  limitName: "[string]Usage Limit Model Name"
  counterName: "[string]Counter Name"
  verifyType: "[string]Type of verification"
  count: "[int]Count Value"
  multiplyValueSpecifyingQuantity: "[bool]Whether to multiply the value used for verification when specifying the quantity"
  timeOffsetToken: "[string]Time offset token"
transaction.service("limit").verify.verify_counter_by_user_id({
    namespaceName="[string]Namespace name",
    userId="[string]User ID",
    limitName="[string]Usage Limit Model Name",
    counterName="[string]Counter Name",
    verifyType="[string]Type of verification",
    count="[int]Count Value",
    multiplyValueSpecifyingQuantity="[bool]Whether to multiply the value used for verification when specifying the quantity",
    timeOffsetToken="[string]Time offset token",
})

Consume Action

Gs2Limit:CountUpByUserId

Count-up by User ID

Increments the specified user’s counter by the specified count-up value. If maxValue is specified, the counter will not exceed that limit; an Overflow error is returned if the operation would exceed the maximum. If the counter does not yet exist, it is automatically created.

Quantity specification supported: YES

Reversible action: YES

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
limitNamestring
~ 128 charsUsage Limit Model Name
The name of the limit model that this counter belongs to. Determines the reset schedule (daily, weekly, monthly, etc.) applied to this counter’s value.
counterNamestring
~ 128 charsCounter Name
A unique identifier for this counter within the limit model. Multiple counters can share the same limit model with different names, allowing separate usage tracking (e.g., one counter per quest or per product) without creating separate limit models.
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
countUpValueint11 ~ 2147483646Amount to count up
maxValueint1 ~ 2147483646Maximum value allowed to count up
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2Limit:CountUpByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "limitName": "[string]Usage Limit Model Name",
        "counterName": "[string]Counter Name",
        "userId": "[string]User ID",
        "countUpValue": "[int]Amount to count up",
        "maxValue": "[int]Maximum value allowed to count up",
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2Limit:CountUpByUserId
request:
  namespaceName: "[string]Namespace name"
  limitName: "[string]Usage Limit Model Name"
  counterName: "[string]Counter Name"
  userId: "[string]User ID"
  countUpValue: "[int]Amount to count up"
  maxValue: "[int]Maximum value allowed to count up"
  timeOffsetToken: "[string]Time offset token"
transaction.service("limit").consume.count_up_by_user_id({
    namespaceName="[string]Namespace name",
    limitName="[string]Usage Limit Model Name",
    counterName="[string]Counter Name",
    userId="[string]User ID",
    countUpValue="[int]Amount to count up",
    maxValue="[int]Maximum value allowed to count up",
    timeOffsetToken="[string]Time offset token",
})

Acquire Action

Gs2Limit:CountDownByUserId

Count-down by User ID

Decrements the specified user’s counter by the specified count-down value. The counter value will not go below 0.

Quantity specification supported: YES

Reversible action: YES

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
limitNamestring
~ 128 charsUsage Limit Model Name
The name of the limit model that this counter belongs to. Determines the reset schedule (daily, weekly, monthly, etc.) applied to this counter’s value.
counterNamestring
~ 128 charsCounter Name
A unique identifier for this counter within the limit model. Multiple counters can share the same limit model with different names, allowing separate usage tracking (e.g., one counter per quest or per product) without creating separate limit models.
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
countDownValueint11 ~ 2147483646Amount to count down
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2Limit:CountDownByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "limitName": "[string]Usage Limit Model Name",
        "counterName": "[string]Counter Name",
        "userId": "[string]User ID",
        "countDownValue": "[int]Amount to count down",
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2Limit:CountDownByUserId
request:
  namespaceName: "[string]Namespace name"
  limitName: "[string]Usage Limit Model Name"
  counterName: "[string]Counter Name"
  userId: "[string]User ID"
  countDownValue: "[int]Amount to count down"
  timeOffsetToken: "[string]Time offset token"
transaction.service("limit").acquire.count_down_by_user_id({
    namespaceName="[string]Namespace name",
    limitName="[string]Usage Limit Model Name",
    counterName="[string]Counter Name",
    userId="[string]User ID",
    countDownValue="[int]Amount to count down",
    timeOffsetToken="[string]Time offset token",
})

Gs2Limit:DeleteCounterByUserId

Delete Counter by User ID

Deletes the specified user’s counter, resetting the usage count. This effectively removes the limit restriction for this counter, allowing the user to start counting from 0 again.

Quantity specification supported: NO

Reversible action: NO

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
limitNamestring
~ 128 charsUsage Limit Model Name
The name of the limit model that this counter belongs to. Determines the reset schedule (daily, weekly, monthly, etc.) applied to this counter’s value.
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
counterNamestring
~ 128 charsCounter Name
A unique identifier for this counter within the limit model. Multiple counters can share the same limit model with different names, allowing separate usage tracking (e.g., one counter per quest or per product) without creating separate limit models.
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2Limit:DeleteCounterByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "limitName": "[string]Usage Limit Model Name",
        "userId": "[string]User ID",
        "counterName": "[string]Counter Name",
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2Limit:DeleteCounterByUserId
request:
  namespaceName: "[string]Namespace name"
  limitName: "[string]Usage Limit Model Name"
  userId: "[string]User ID"
  counterName: "[string]Counter Name"
  timeOffsetToken: "[string]Time offset token"
transaction.service("limit").acquire.delete_counter_by_user_id({
    namespaceName="[string]Namespace name",
    limitName="[string]Usage Limit Model Name",
    userId="[string]User ID",
    counterName="[string]Counter Name",
    timeOffsetToken="[string]Time offset token",
})