Skip to content

Commit

Permalink
fix: fixed data race in result (schemata caching)
Browse files Browse the repository at this point in the history
Signed-off-by: Frederic BIDON <[email protected]>
  • Loading branch information
fredbi committed Mar 4, 2024
1 parent e818230 commit 2ae1354
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 13 deletions.
33 changes: 30 additions & 3 deletions result.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,23 @@ func (r *Result) mergeForField(obj map[string]interface{}, field string, other *
if r.fieldSchemata == nil {
r.fieldSchemata = make([]fieldSchemata, len(obj))
}
// clone other schemata, as other is about to be redeemed to the pool
clone := schemata{one: new(spec.Schema), multiple: nil}
if other.rootObjectSchemata.one != nil {
*clone.one = *other.rootObjectSchemata.one
}
if len(other.rootObjectSchemata.multiple) > 0 {
clone.multiple = make([]*spec.Schema, len(other.rootObjectSchemata.multiple))
for idx := 0; idx < len(other.rootObjectSchemata.multiple); idx++ {
s := new(spec.Schema)
*s = *other.rootObjectSchemata.multiple[idx]
clone.multiple[idx] = s
}
}
r.fieldSchemata = append(r.fieldSchemata, fieldSchemata{
obj: obj,
field: field,
schemata: other.rootObjectSchemata,
schemata: clone,
})
}
if other.wantsRedeemOnMerge {
Expand All @@ -220,12 +233,26 @@ func (r *Result) mergeForSlice(slice reflect.Value, i int, other *Result) *Resul
if r.itemSchemata == nil {
r.itemSchemata = make([]itemSchemata, slice.Len())
}
// clone other schemata, as other is about to be redeemed to the pool
clone := schemata{one: new(spec.Schema), multiple: nil}
if other.rootObjectSchemata.one != nil {
*clone.one = *other.rootObjectSchemata.one
}
if len(other.rootObjectSchemata.multiple) > 0 {
clone.multiple = make([]*spec.Schema, len(other.rootObjectSchemata.multiple))
for idx := 0; idx < len(other.rootObjectSchemata.multiple); idx++ {
s := new(spec.Schema)
*s = *other.rootObjectSchemata.multiple[idx]
clone.multiple[idx] = s
}
}
r.itemSchemata = append(r.itemSchemata, itemSchemata{
slice: slice,
index: i,
schemata: other.rootObjectSchemata,
schemata: clone,
})
}

if other.wantsRedeemOnMerge {
pools.poolOfResults.RedeemResult(other)
}
Expand Down Expand Up @@ -502,7 +529,7 @@ func (s *schemata) Slice() []*spec.Schema {
return s.multiple
}

// appendSchemata appends the schemata in other to s. It mutated s in-place.
// appendSchemata appends the schemata in other to s. It mutates s in-place.
func (s *schemata) Append(other schemata) {
if other.one == nil && len(other.multiple) == 0 {
return
Expand Down
10 changes: 0 additions & 10 deletions schema_props_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,6 @@ func TestSchemaPropsValidator_EdgeCases(t *testing.T) {
res := s.Validate(data)
require.NotNil(t, res)
require.Empty(t, res.Errors)

/* TODO(fred)
t.Run("validator should run once", func(t *testing.T) {
// we should not do that: the pool chain list is populated with a duplicate: needs a reset
t.Cleanup(resetPools)
require.NotPanics(t, func() {
_ = s.Validate(data)
})
})
*/
})

t.Run("should NOT validate unformatted string", func(t *testing.T) {
Expand Down

0 comments on commit 2ae1354

Please sign in to comment.