Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix panic due to bad iter.Seq implementation #4

Merged
merged 1 commit into from
Oct 4, 2024
Merged

Conversation

PapaCharlie
Copy link
Member

The following panic was occasionally crashing users of this library:

panic: runtime error: range function continued iteration after function for loop body returned false

goroutine 372057 [running]:
github.com/linkedin/diderot/internal/cache.(*WatchableValue[...]).notifySubscribers-range1({0x17a9ae0?, 0xc019746070?, 0x23db800?})
        /export/home/tester/.cache/go/pkg/mod/github.com/linkedin/[email protected]/internal/cache/watchable_value.go:319 +0x1c5
github.com/linkedin/diderot/internal/cache.(*WatchableValue[...]).iterateSubscribers.func1-range1({0xc06428dc68, 0x472988, 0x23db800?})
        /export/home/tester/.cache/go/pkg/mod/github.com/linkedin/[email protected]/internal/cache/watchable_value.go:406 +0x143
github.com/linkedin/diderot/internal/cache.(*SubscriberSet[...]).Iterator.func2.1({0x1265ec0?, 0xc094fad000})
        /export/home/tester/.cache/go/pkg/mod/github.com/linkedin/[email protected]/internal/cache/subscriber_set.go:127 +0x90
sync.(*Map).Range(0xc014669040?, 0xc06428dd28)
        /export/home/tester/.go/1.23.0/src/sync/map.go:501 +0x1f8
github.com/linkedin/diderot/internal/cache.(*SubscriberSet[...]).Iterator.func2()
        /export/home/tester/.cache/go/pkg/mod/github.com/linkedin/[email protected]/internal/cache/subscriber_set.go:122 +0x45
github.com/linkedin/diderot/internal/cache.(*WatchableValue[...]).iterateSubscribers.func1()
        /export/home/tester/.cache/go/pkg/mod/github.com/linkedin/[email protected]/internal/cache/watchable_value.go:398 +0x139
github.com/linkedin/diderot/internal/cache.(*WatchableValue[...]).notifySubscribers(0x17e17c0, {0xc01cc25c00, {0x24c6ac40, 0xede925733, 0x23db800}, {0xc1b835ece4e2c066, 0x70e6bc3a557, 0x23db800}, 0x2, {0xc01ce9f8c0, ...}}, ...)
        /export/home/tester/.cache/go/pkg/mod/github.com/linkedin/[email protected]/internal/cache/watchable_value.go:319 +0x1be
github.com/linkedin/diderot/internal/cache.(*WatchableValue[...]).startNotificationLoop.func1()
        /export/home/tester/.cache/go/pkg/mod/github.com/linkedin/[email protected]/internal/cache/watchable_value.go:282 +0x2b5
created by github.com/linkedin/diderot/internal/cache.(*WatchableValue[...]).startNotificationLoop in goroutine 117232
        /export/home/tester/.cache/go/pkg/mod/github.com/linkedin/[email protected]/internal/cache/watchable_value.go:261 +0x87

This is due to the fact that the nested for loop continues after yield returns false. Using iter.Seq makes for nice syntactic sugar, but can be occasionally tricky to write.

The following panic was occasionally crashing users of this library:
```
panic: runtime error: range function continued iteration after function for loop body returned false

goroutine 372057 [running]:
github.com/linkedin/diderot/internal/cache.(*WatchableValue[...]).notifySubscribers-range1({0x17a9ae0?, 0xc019746070?, 0x23db800?})
        /export/home/tester/.cache/go/pkg/mod/github.com/linkedin/[email protected]/internal/cache/watchable_value.go:319 +0x1c5
github.com/linkedin/diderot/internal/cache.(*WatchableValue[...]).iterateSubscribers.func1-range1({0xc06428dc68, 0x472988, 0x23db800?})
        /export/home/tester/.cache/go/pkg/mod/github.com/linkedin/[email protected]/internal/cache/watchable_value.go:406 +0x143
github.com/linkedin/diderot/internal/cache.(*SubscriberSet[...]).Iterator.func2.1({0x1265ec0?, 0xc094fad000})
        /export/home/tester/.cache/go/pkg/mod/github.com/linkedin/[email protected]/internal/cache/subscriber_set.go:127 +0x90
sync.(*Map).Range(0xc014669040?, 0xc06428dd28)
        /export/home/tester/.go/1.23.0/src/sync/map.go:501 +0x1f8
github.com/linkedin/diderot/internal/cache.(*SubscriberSet[...]).Iterator.func2()
        /export/home/tester/.cache/go/pkg/mod/github.com/linkedin/[email protected]/internal/cache/subscriber_set.go:122 +0x45
github.com/linkedin/diderot/internal/cache.(*WatchableValue[...]).iterateSubscribers.func1()
        /export/home/tester/.cache/go/pkg/mod/github.com/linkedin/[email protected]/internal/cache/watchable_value.go:398 +0x139
github.com/linkedin/diderot/internal/cache.(*WatchableValue[...]).notifySubscribers(0x17e17c0, {0xc01cc25c00, {0x24c6ac40, 0xede925733, 0x23db800}, {0xc1b835ece4e2c066, 0x70e6bc3a557, 0x23db800}, 0x2, {0xc01ce9f8c0, ...}}, ...)
        /export/home/tester/.cache/go/pkg/mod/github.com/linkedin/[email protected]/internal/cache/watchable_value.go:319 +0x1be
github.com/linkedin/diderot/internal/cache.(*WatchableValue[...]).startNotificationLoop.func1()
        /export/home/tester/.cache/go/pkg/mod/github.com/linkedin/[email protected]/internal/cache/watchable_value.go:282 +0x2b5
created by github.com/linkedin/diderot/internal/cache.(*WatchableValue[...]).startNotificationLoop in goroutine 117232
        /export/home/tester/.cache/go/pkg/mod/github.com/linkedin/[email protected]/internal/cache/watchable_value.go:261 +0x87
```
This is due to the fact that the nested for loop continues after `yield` returns
false. Using `iter.Seq` makes for nice syntactic sugar, but can be occasionally
tricky to write.
@PapaCharlie PapaCharlie merged commit f886eed into master Oct 4, 2024
2 checks passed
@PapaCharlie PapaCharlie deleted the pc/panic branch October 4, 2024 22:42
PapaCharlie added a commit that referenced this pull request Oct 5, 2024
Just as a precautionary measure, this updates an existing unit test to
specifically check whether the fix introduced in #4 works as expected. This has
been tested by reverting #4 and checking that it does indeed trigger the panic,
and with #4 the panic is fixed.
PapaCharlie added a commit that referenced this pull request Oct 7, 2024
Just as a precautionary measure, this updates an existing unit test to
specifically check whether the fix introduced in #4 works as expected.
This has been tested by reverting #4 and checking that it does indeed
trigger the panic, and with #4 the panic is fixed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants