merged from gramsrv upstream
This commit is contained in:
parent
79c64ee916
commit
21a0856587
651 changed files with 54774 additions and 4590 deletions
|
|
@ -103,6 +103,29 @@ func (c *BatchCache) Prime(viewerUserID int64, users []domain.User) {
|
|||
}
|
||||
}
|
||||
|
||||
// PrimeExpected preheats one viewer with the complete result of a bounded batch
|
||||
// projection. IDs omitted by the resolver are negative-cached as missing, so a
|
||||
// later fan-out builder cannot silently fall back to a per-viewer ByIDs query.
|
||||
// System users remain locally synthesised even when the resolver omits them.
|
||||
func (c *BatchCache) PrimeExpected(viewerUserID int64, expectedIDs []int64, users []domain.User) {
|
||||
if c == nil || viewerUserID == 0 {
|
||||
return
|
||||
}
|
||||
c.Prime(viewerUserID, users)
|
||||
byID := c.viewerUsers(viewerUserID)
|
||||
missing := c.viewerMissing(viewerUserID)
|
||||
for _, id := range uniqueIDs(expectedIDs) {
|
||||
if _, ok := byID[id]; ok {
|
||||
continue
|
||||
}
|
||||
if system, ok := domain.SystemUserByID(id); ok {
|
||||
byID[id] = system
|
||||
continue
|
||||
}
|
||||
missing[id] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *BatchCache) viewerUsers(viewerUserID int64) map[int64]domain.User {
|
||||
if byID, ok := c.byViewer[viewerUserID]; ok {
|
||||
return byID
|
||||
|
|
|
|||
|
|
@ -86,6 +86,42 @@ func TestBatchCachePrimeServesWithoutResolver(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBatchCachePrimeExpectedNegativeCachesOmittedUsers(t *testing.T) {
|
||||
resolver := &captureUserResolver{
|
||||
users: map[int64]domain.User{
|
||||
1000000002: {ID: 1000000002, FirstName: "must not be loaded"},
|
||||
},
|
||||
}
|
||||
cache := NewBatchCache(resolver)
|
||||
const viewer = int64(1000000003)
|
||||
cache.PrimeExpected(viewer,
|
||||
[]int64{1000000001, 1000000002, domain.OfficialSystemUserID},
|
||||
[]domain.User{{ID: 1000000001, FirstName: "Primed"}},
|
||||
)
|
||||
|
||||
got, err := cache.UsersForView(context.Background(), viewer,
|
||||
[]int64{1000000001, 1000000002, domain.OfficialSystemUserID})
|
||||
if err != nil {
|
||||
t.Fatalf("UsersForView: %v", err)
|
||||
}
|
||||
if len(resolver.calls) != 0 {
|
||||
t.Fatalf("resolver calls = %+v, want none after complete batch preheat", resolver.calls)
|
||||
}
|
||||
byID := make(map[int64]domain.User, len(got))
|
||||
for _, user := range got {
|
||||
byID[user.ID] = user
|
||||
}
|
||||
if byID[1000000001].FirstName != "Primed" {
|
||||
t.Fatalf("primed user = %+v", byID[1000000001])
|
||||
}
|
||||
if _, ok := byID[1000000002]; ok {
|
||||
t.Fatalf("omitted user unexpectedly resolved: %+v", byID[1000000002])
|
||||
}
|
||||
if _, ok := byID[domain.OfficialSystemUserID]; !ok {
|
||||
t.Fatalf("system user missing from local synthesis: %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
type resolverCall struct {
|
||||
viewerUserID int64
|
||||
ids []int64
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue