unified-storage: implement sqlkv Save method (#115458)

* unified-storage: sqlkv save method
This commit is contained in:
Will Assis
2025-12-19 14:27:06 -05:00
committed by GitHub
parent 14c595f206
commit 4164239f56
15 changed files with 534 additions and 47 deletions
@@ -21,6 +21,19 @@ import (
"github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate"
)
type contextKey string
const txKey contextKey = "rvmanager_db_tx"
func ContextWithTx(ctx context.Context, tx db.Tx) context.Context {
return context.WithValue(ctx, txKey, tx)
}
func TxFromCtx(ctx context.Context) (db.Tx, bool) {
tx, ok := ctx.Value(txKey).(db.Tx)
return tx, ok
}
var tracer = otel.Tracer("github.com/grafana/grafana/pkg/storage/unified/sql/rvmanager")
var (
@@ -294,7 +307,7 @@ func (m *ResourceVersionManager) execBatch(ctx context.Context, group, resource
// Allocate the RVs
for i, guid := range guids {
guidToRV[guid] = rv
guidToSnowflakeRV[guid] = snowflakeFromRv(rv)
guidToSnowflakeRV[guid] = SnowflakeFromRv(rv)
rvs[i] = rv
rv++
}
@@ -353,10 +366,20 @@ func (m *ResourceVersionManager) execBatch(ctx context.Context, group, resource
// takes a unix microsecond rv and transforms into a snowflake format. The timestamp is converted from microsecond to
// millisecond (the integer division) and the remainder is saved in the stepbits section. machine id is always 0
func snowflakeFromRv(rv int64) int64 {
func SnowflakeFromRv(rv int64) int64 {
return (((rv / 1000) - snowflake.Epoch) << (snowflake.NodeBits + snowflake.StepBits)) + (rv % 1000)
}
// helper utility to compare two RVs. The first RV must be in snowflake format. Will convert rv2 to snowflake and retry
// if comparison fails
func IsRvEqual(rv1, rv2 int64) bool {
if rv1 == rv2 {
return true
}
return rv1 == SnowflakeFromRv(rv2)
}
// Lock locks the resource version for the given key
func (m *ResourceVersionManager) Lock(ctx context.Context, x db.ContextExecer, group, resource string) (nextRV int64, err error) {
// 1. Lock the row and prevent concurrent updates until the transaction is committed