mirror of https://github.com/hashicorp/consul
3c44116a8f
This continues the work done in #14908 where a crude solution to prevent a goroutine leak was implemented. The former code would launch a perpetual goroutine family every iteration (+1 +1) and the fixed code simply caused a new goroutine family to first cancel the prior one to prevent the leak (-1 +1 == 0). This PR refactors this code completely to: - make it more understandable - remove the recursion-via-goroutine strangeness - prevent unnecessary RPC fetches when the prior one has errored. The core issue arose from a conflation of the entry.Fetching field to mean: - there is an RPC (blocking query) in flight right now - there is a goroutine running to manage the RPC fetch retry loop The problem is that the goroutine-leak-avoidance check would treat Fetching like (2), but within the body of a goroutine it would flip that boolean back to false before the retry sleep. This would cause a new chain of goroutines to launch which #14908 would correct crudely. The refactored code uses a plain for-loop and changes the semantics to track state for "is there a goroutine associated with this cache entry" instead of the former. We use a uint64 unique identity per goroutine instead of a boolean so that any orphaned goroutines can tell when they've been replaced when the expiry loop deletes a cache entry while the goroutine is still running and is later replaced. |
||
---|---|---|
.. | ||
testdata | ||
agent_limits.go | ||
builder.go | ||
builder_oss.go | ||
builder_oss_test.go | ||
builder_test.go | ||
config.go | ||
config_oss.go | ||
default.go | ||
default_oss.go | ||
deprecated.go | ||
deprecated_test.go | ||
doc.go | ||
file_watcher.go | ||
file_watcher_test.go | ||
flags.go | ||
flags_test.go | ||
flagset.go | ||
golden_test.go | ||
limits.go | ||
limits_windows.go | ||
merge.go | ||
merge_test.go | ||
ratelimited_file_watcher.go | ||
ratelimited_file_watcher_test.go | ||
runtime.go | ||
runtime_oss.go | ||
runtime_oss_test.go | ||
runtime_test.go | ||
segment_oss.go | ||
segment_oss_test.go |