nanokv
    Preparing search index...

    Interface AtomicOperation<E, Q>

    An atomic operation on NanoKV allows for multiple updates to be conducted in a single, indivisible transaction. These operations require explicit commitment through the invocation of the commit method, as they do not auto-commit by default.

    Atomic operations facilitate the execution of several mutations on the key-value store in a single transaction, ensuring consistency. They also enable conditional updates by incorporating AtomicChecks, which verify that mutations only occur if the key-value pair meets specific versionstamp criteria. Should any check fail, the entire operation is aborted, leaving the store unchanged.

    The sequence of mutations is preserved as per the order specified in the operation, with checks executed prior to any mutations, although the sequence of checks is not observable.

    Atomic operations are instrumental in implementing optimistic locking, a strategy where a mutation is executed only if the key-value pair has remained unaltered since the last read operation. This is achieved by including a check to verify that the versionstamp of the key-value pair has not changed since it was last accessed. If the check fails, the mutation is aborted, and the operation is considered unsuccessful. The read-modify-write cycle can be repeated in a loop until it completes successfully.

    The commit method of an atomic operation yields a result indicating the success of checks and the execution of mutations. A KvCommitError with an ok: false property signifies failure due to a check. Other failures, such as storage errors or invalid values, trigger exceptions. Successful operations return a KvCommitResult object with an ok: true property, along with the versionstamp of the committed value.

    interface AtomicOperation<
        E extends KvEntry = KvEntry,
        Q extends KvQueueEntry = KvQueueEntry,
    > {
        check(...entries: AtomicCheck<E["key"]>[]): this;
        commit(): Promise<KvCommitResult | KvCommitError>;
        delete<K extends KvKey>(key: K): this;
        dequeue(
            ...keys: { key: Q["key"]; schedule: number; sequence: bigint }[],
        ): this;
        enqueue<K extends KvKey>(
            key: K,
            value: DistributiveProp<Extract<Q, { key: K }>, "value">,
            options?: { delay?: number; schedule?: number },
        ): this;
        merge(operation: AtomicOperation): this;
        set<K extends KvKey>(
            key: K,
            value: DistributiveProp<Extract<E, { key: K }>, "value">,
            options?: { expireIn?: number },
        ): this;
    }

    Type Parameters

    Index

    Methods

    • Add to the operation a check that ensures that the versionstamp of the key-value pair in the KV store matches the given versionstamp. If the check fails, the entire operation will fail and no mutations will be performed during the commit.

      Parameters

      Returns this

    • Commit the operation to the KV store. Returns a value indicating whether checks passed and mutations were performed. If the operation failed because of a failed check, the return value will be a KvCommitError with an ok: false property. If the operation failed for any other reason (storage error, invalid value, etc.), an exception will be thrown. If the operation succeeded, the return value will be a KvCommitResult object with a ok: true property and the versionstamp of the value committed to KV.

      If the commit returns ok: false, one may create a new atomic operation with updated checks and mutations and attempt to commit it again. See the note on optimistic locking in the documentation for AtomicOperation.

      Returns Promise<KvCommitResult | KvCommitError>

    • Add to the operation a mutation that deletes the specified key if all checks pass during the commit.

      Type Parameters

      Parameters

      • key: K

      Returns this

    • Add to the operation a mutation that dequeues a value from the queue if all checks pass during the commit.

      Parameters

      • ...keys: { key: Q["key"]; schedule: number; sequence: bigint }[]

      Returns this

    • Add to the operation a mutation that enqueues a value into the queue if all checks pass during the commit.

      Type Parameters

      Parameters

      • key: K
      • value: DistributiveProp<Extract<Q, { key: K }>, "value">
      • Optionaloptions: { delay?: number; schedule?: number }

      Returns this

    • Add to the operation a mutation that sets the value of the specified key to the specified value if all checks pass during the commit.

      Optionally an expireIn option can be specified to set a time-to-live (TTL) for the key. The TTL is specified in milliseconds, and the key will be deleted from the database at earliest after the specified number of milliseconds have elapsed. Once the specified duration has passed, the key may still be visible for some additional time. If the expireIn option is not specified, the key will not expire.

      Type Parameters

      Parameters

      • key: K
      • value: DistributiveProp<Extract<E, { key: K }>, "value">
      • Optionaloptions: { expireIn?: number }

      Returns this