112 lines
3.9 KiB
Go
112 lines
3.9 KiB
Go
package redisstate
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
// registeredRecord stores the strict Redis JSON shape of one registered
|
|
// race name. The canonical key is stored only as the Redis key suffix and
|
|
// is not duplicated inside the blob.
|
|
type registeredRecord struct {
|
|
UserID string `json:"user_id"`
|
|
RaceName string `json:"race_name"`
|
|
SourceGameID string `json:"source_game_id"`
|
|
RegisteredAtMS int64 `json:"registered_at_ms"`
|
|
}
|
|
|
|
// reservationStatusReserved marks a per-game race name reservation that
|
|
// has not yet been promoted by capability evaluation.
|
|
const reservationStatusReserved = "reserved"
|
|
|
|
// reservationStatusPending marks a reservation that has been promoted to
|
|
// pending_registration by the capability evaluator at game_finished.
|
|
const reservationStatusPending = "pending_registration"
|
|
|
|
// reservationRecord stores the strict Redis JSON shape of one per-game
|
|
// race name reservation. The game_id and canonical key are carried by the
|
|
// Redis key suffix; the blob never duplicates them.
|
|
type reservationRecord struct {
|
|
UserID string `json:"user_id"`
|
|
RaceName string `json:"race_name"`
|
|
ReservedAtMS int64 `json:"reserved_at_ms"`
|
|
Status string `json:"status"`
|
|
EligibleUntilMS *int64 `json:"eligible_until_ms,omitempty"`
|
|
}
|
|
|
|
// canonicalLookupRecord stores the eager canonical-lookup cache entry
|
|
// used by Check to return availability without scanning the authoritative
|
|
// keys. GameID is populated only for reservation and pending_registration
|
|
// kinds; it is omitted for registered bindings.
|
|
type canonicalLookupRecord struct {
|
|
Kind string `json:"kind"`
|
|
HolderUserID string `json:"holder_user_id"`
|
|
GameID string `json:"game_id,omitempty"`
|
|
}
|
|
|
|
// marshalRegisteredRecord encodes record into the strict Redis JSON shape
|
|
// used for registered race names.
|
|
func marshalRegisteredRecord(record registeredRecord) ([]byte, error) {
|
|
payload, err := json.Marshal(record)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("marshal redis registered race name record: %w", err)
|
|
}
|
|
|
|
return payload, nil
|
|
}
|
|
|
|
// unmarshalRegisteredRecord decodes payload from the strict Redis JSON
|
|
// shape used for registered race names.
|
|
func unmarshalRegisteredRecord(payload []byte) (registeredRecord, error) {
|
|
var record registeredRecord
|
|
if err := decodeStrictJSON("decode redis registered race name record", payload, &record); err != nil {
|
|
return registeredRecord{}, err
|
|
}
|
|
|
|
return record, nil
|
|
}
|
|
|
|
// marshalReservationRecord encodes record into the strict Redis JSON
|
|
// shape used for per-game race name reservations.
|
|
func marshalReservationRecord(record reservationRecord) ([]byte, error) {
|
|
payload, err := json.Marshal(record)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("marshal redis race name reservation record: %w", err)
|
|
}
|
|
|
|
return payload, nil
|
|
}
|
|
|
|
// unmarshalReservationRecord decodes payload from the strict Redis JSON
|
|
// shape used for per-game race name reservations.
|
|
func unmarshalReservationRecord(payload []byte) (reservationRecord, error) {
|
|
var record reservationRecord
|
|
if err := decodeStrictJSON("decode redis race name reservation record", payload, &record); err != nil {
|
|
return reservationRecord{}, err
|
|
}
|
|
|
|
return record, nil
|
|
}
|
|
|
|
// marshalCanonicalLookupRecord encodes record into the strict Redis JSON
|
|
// shape used for canonical-lookup cache entries.
|
|
func marshalCanonicalLookupRecord(record canonicalLookupRecord) ([]byte, error) {
|
|
payload, err := json.Marshal(record)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("marshal redis race name canonical lookup record: %w", err)
|
|
}
|
|
|
|
return payload, nil
|
|
}
|
|
|
|
// unmarshalCanonicalLookupRecord decodes payload from the strict Redis
|
|
// JSON shape used for canonical-lookup cache entries.
|
|
func unmarshalCanonicalLookupRecord(payload []byte) (canonicalLookupRecord, error) {
|
|
var record canonicalLookupRecord
|
|
if err := decodeStrictJSON("decode redis race name canonical lookup record", payload, &record); err != nil {
|
|
return canonicalLookupRecord{}, err
|
|
}
|
|
|
|
return record, nil
|
|
}
|