Created
November 30, 2021 22:55
-
-
Save emcfarlane/965cf56e14ebddf0866f9a19000f0e62 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// counter is a chunked firestore counter. | |
type counter struct { | |
id string | |
sync.Mutex | |
value big.Int | |
limit big.Int | |
} | |
type Counter struct { | |
ID string | |
Value string | |
} | |
func (s *Server) newSerialNumber(ctx context.Context, counterID string) (*big.Int, error) { | |
s.counter.Lock() | |
defer s.counter.Unlock() | |
value := new(big.Int).Set(&s.counter.value) | |
limit := new(big.Int).Set(&s.counter.limit) | |
if r := value.Cmp(limit); r >= 0 { | |
s.store.Collection("counters").Doc(counterID) | |
if err := s.store.RunTransaction(ctx, func(ctx context.Context, tx *firestore.Transaction) error { | |
snap, err := tx.Get(doc) | |
if err != nil { | |
return err | |
} | |
var counter Counter | |
if err := snap.DataTo(&counter); err != nil { | |
return err | |
} | |
if err := value.UnmarshalText([]byte(counter.Value)); err != nil { | |
return err | |
} | |
limit.SetInt64(counterChunkSize).Add(limit, value) | |
return tx.Set(doc, map[string]interface{}{ | |
"value": limit.String(), | |
}, firestore.MergeAll) | |
}); err != nil { | |
return nil, err | |
} | |
} | |
// update values after transaction | |
result := big.NewInt(1) | |
s.counter.value.Set(value.Add(value, result)) | |
s.counter.limit.Set(limit) | |
return result.Set(&s.counter.value), nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment