databroker: fix in-memory backend deadlock (#3300)

This commit is contained in:
Caleb Doxsey 2022-04-27 19:33:29 +00:00 committed by GitHub
parent f73c5c615f
commit 2e1366c417
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 18 deletions

View file

@ -188,6 +188,10 @@ func (backend *Backend) Lease(_ context.Context, leaseName, leaseID string, ttl
// Put puts a record into the in-memory store. // Put puts a record into the in-memory store.
func (backend *Backend) Put(ctx context.Context, records []*databroker.Record) (serverVersion uint64, err error) { func (backend *Backend) Put(ctx context.Context, records []*databroker.Record) (serverVersion uint64, err error) {
backend.mu.Lock()
defer backend.mu.Unlock()
defer backend.onChange.Broadcast(ctx)
recordTypes := map[string]struct{}{} recordTypes := map[string]struct{}{}
for _, record := range records { for _, record := range records {
if record == nil { if record == nil {
@ -200,10 +204,6 @@ func (backend *Backend) Put(ctx context.Context, records []*databroker.Record) (
Str("db_type", record.Type) Str("db_type", record.Type)
}) })
backend.mu.Lock()
defer backend.mu.Unlock()
defer backend.onChange.Broadcast(ctx)
backend.recordChange(record) backend.recordChange(record)
c, ok := backend.lookup[record.GetType()] c, ok := backend.lookup[record.GetType()]

View file

@ -28,22 +28,36 @@ func TestBackend(t *testing.T) {
}) })
t.Run("get record", func(t *testing.T) { t.Run("get record", func(t *testing.T) {
data := new(anypb.Any) data := new(anypb.Any)
sv, err := backend.Put(ctx, []*databroker.Record{{ sv, err := backend.Put(ctx, []*databroker.Record{
Type: "TYPE", {
Id: "abcd", Type: "TYPE",
Data: data, Id: "a",
}}) Data: data,
},
{
Type: "TYPE",
Id: "b",
Data: data,
},
{
Type: "TYPE",
Id: "c",
Data: data,
},
})
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, backend.serverVersion, sv) assert.Equal(t, backend.serverVersion, sv)
record, err := backend.Get(ctx, "TYPE", "abcd") for i, id := range []string{"a", "b", "c"} {
require.NoError(t, err) record, err := backend.Get(ctx, "TYPE", id)
if assert.NotNil(t, record) { require.NoError(t, err)
assert.Equal(t, data, record.Data) if assert.NotNil(t, record) {
assert.Nil(t, record.DeletedAt) assert.Equal(t, data, record.Data)
assert.Equal(t, "abcd", record.Id) assert.Nil(t, record.DeletedAt)
assert.NotNil(t, record.ModifiedAt) assert.Equal(t, id, record.Id)
assert.Equal(t, "TYPE", record.Type) assert.NotNil(t, record.ModifiedAt)
assert.Equal(t, uint64(1), record.Version) assert.Equal(t, "TYPE", record.Type)
assert.Equal(t, uint64(i+1), record.Version)
}
} }
}) })
t.Run("delete record", func(t *testing.T) { t.Run("delete record", func(t *testing.T) {