internal/event: fix log processor race (#5401)
The cloud events formatter Process function would call the signer without protecting it, which was racy with the Rotate function.
This commit is contained in:
1 parent
ae916727e5
commit
1cbe1ca463
2 files changed
+43
No files matched your search
@@ -113,6 +113,15 @@ func (f *cloudEventsFormatterFilter) Rotate(w wrapping.Wrapper, _ ...Option) err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *cloudEventsFormatterFilter) Process(ctx context.Context, e *eventlogger.Event) (*eventlogger.Event, error) {
|
||||
// The embedded FormatterFilter's Process function calls the signer, but doesn't know
|
||||
// about the lock, leading to a potential race condition. We take the lock here to ensure
|
||||
// that the signer is only accessed by one goroutine at a time.
|
||||
f.l.RLock()
|
||||
defer f.l.RUnlock()
|
||||
return f.FormatterFilter.Process(ctx, e)
|
||||
}
|
||||
|
||||
func newPredicate(allow, deny []*filter) func(ctx context.Context, ce any) (bool, error) {
|
||||
return func(ctx context.Context, ce any) (bool, error) {
|
||||
if len(allow) == 0 && len(deny) == 0 {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -395,3 +396,36 @@ func Test_cloudEventsFormatter_Rotate(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_cloudEventsFormatter_Race(t *testing.T) {
|
||||
testUrl, err := url.Parse("https://[::1]")
|
||||
require.NoError(t, err)
|
||||
|
||||
testNode, err := newCloudEventsFormatterFilter(testUrl, cloudevents.FormatJSON, WithSchema(testUrl))
|
||||
require.NoError(t, err)
|
||||
|
||||
start := make(chan struct{})
|
||||
wg := new(sync.WaitGroup)
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
<-start
|
||||
for i := 0; i < 10; i++ {
|
||||
_ = testNode.Rotate(testWrapper(t))
|
||||
}
|
||||
}()
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
<-start
|
||||
for i := 0; i < 10; i++ {
|
||||
_, _ = testNode.Process(context.Background(), &eventlogger.Event{
|
||||
Type: "test",
|
||||
CreatedAt: time.Now(),
|
||||
Payload: "test-data",
|
||||
})
|
||||
}
|
||||
}()
|
||||
close(start)
|
||||
wg.Wait()
|
||||
}
|
||||
Reference in new issue
Block a user