Skip to content

[NEW] GET/SET CAS FLAG #12485

@tomidotomicode

Description

@tomidotomicode

The problem/use-case that the feature addresses

If the data (value of key) changes during a round-trip to the user interface and back, we need a way to detect this situation in order to avoid dataloss in situations when there are multiple users editing data on same keys.

Description of the feature

Prevent changes to the data when another user has already changed the data behind the scenes.
Implementation as CAS token.

If CAS token does not match current token, then set must fail.
If CAS token matches, then set to given value and create new cas token

First part: Get CAS token

SET hello "Hello, World!"

GET hello CAS
"Hello, World!"
"37eaa6435955b815"

Alternatively:
GETCAS hello
"37eaa6435955b815"

Second part:

SET hello "Hello, You!" CAS "37eaa6435955b815"

If the previous data is still "Hello, World!" this key 'hello' should be set to "Hello, You!", because the CAS token has not changed.
However, if another user has meanwhile changed the data into "Hello, Me!" and thereby changed its CAS token into "37eaa6434791eb9b" then the SET should fail.

In the given example above the tokens have been calculated with simple hashing as follows:

uint64_t simpleCasToken(const uint8_t* data, size_t length) {
uint64_t token = 0;
for (size_t i = 0; i < length; i++) {
token = token * 31 + data[i];
}
return token;
}

void CasTokenToString(uint64_t token, char* buffer) {
sprintf(buffer, "%llx", token);
}

uint64_t stringToCasToken(const char* buffer) {
uint64_t token;
sscanf(buffer, "%llx", &token);
return token;
}

In Redis code there are already tested functions to do similar hashing (such as siphash), which could be used instead.

This functionality would fit with the NX/XX/LT/GT type of "Only Set If Condition" (OSIC) -features.

Alternatives you've considered

Client code can implement this feature by themselves, but this is not atomic and can still happen.
WATCH, MULTI, EXEC can be used to create limited CAS functionality, but using it in a web environment, or in situations when the connections may disconnect, can be very tricky.

Additional information

Relates to #12454 #8361 #5917

Regarding key types that have multiple fields or items, maybe this discussion about inner workings ja Java hashcode may come in handy: https://www.baeldung.com/java-hashcode

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions