Skip to content

atelet: close ateom conns evicted from the dialer cache - #1010

Open
Da Huang (git286) wants to merge 1 commit into
agent-substrate:mainfrom
git286:atelet-close-evicted-ateom-conns
Open

atelet: close ateom conns evicted from the dialer cache#1010
Da Huang (git286) wants to merge 1 commit into
agent-substrate:mainfrom
git286:atelet-close-evicted-ateom-conns

Conversation

@git286

Copy link
Copy Markdown
Collaborator

AteomDialer caches one grpc.ClientConn per worker pod UID in a 256-entry LRU, but the cache had no eviction function: a conn pushed out to make room was forgotten, never closed. grpc does not reclaim an un-Closed conn -- measured against a dead socket, each one holds 4 goroutines, and the channel idle timeout later parks only one of them, so ~3 goroutines and their buffers leak per eviction for the life of the process.

Today evictions need >256 distinct worker pods dialed since atelet started, so the leak is a slow drip reset by restarts. Close evicted conns via the cache's eviction hook. The trade is that an RPC still in flight on a conn that aged to the LRU tail now fails visibly instead of completing on a leaked conn; that needs the same >256-pod churn, and the failure is retryable.

Fixes #1009.

  • Tests pass
  • Appropriate changes to documentation are included in the PR

AteomDialer caches one grpc.ClientConn per worker pod UID in a 256-entry
LRU, but the cache had no eviction function: a conn pushed out to make
room was forgotten, never closed. grpc does not reclaim an un-Closed
conn -- measured against a dead socket, each one holds 4 goroutines, and
the channel idle timeout later parks only one of them, so ~3 goroutines
and their buffers leak per eviction for the life of the process.

Today evictions need >256 distinct worker pods dialed since atelet
started, so the leak is a slow drip reset by restarts. The stats poller
proposed in agent-substrate#961 would sweep every ateoms/ directory (including the
stale ones nothing garbage-collects) through this cache every minute,
turning the drip into hundreds of leaked conns per tick on long-lived
nodes.

Close evicted conns via the cache's eviction hook. The trade is that an
RPC still in flight on a conn that aged to the LRU tail now fails
visibly instead of completing on a leaked conn; that needs the same
>256-pod churn, and the failure is retryable.

Fixes agent-substrate#1009.
Comment thread cmd/atelet/main.go
func newAteomDialer(size int) *AteomDialer {
return &AteomDialer{
conns: lru.NewWithEvictionFunc(size, func(_ lru.Key, value interface{}) {
value.(*grpc.ClientConn).Close()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A made the same comment in #480 : If we blindly close on eviction, can this close a connection which is already in use?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get moves an entry to the front. Every RPC starts with DialAteomPod → Get, so a conn with an RPC in flight was most-recently-used the moment the RPC began. For it to reach the eviction end of the queue mid-RPC, atelet would have to dial 256 other distinct pod UIDs in the window between that RPC starting and finishing, which is extremely unlikely, right?

@juli4n

Copy link
Copy Markdown
Collaborator

IIRC ate-apiserver has the same issue as it also caches connections (to atelet).

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.

# atelet: AteomDialer never closes conns evicted from its LRU cache

2 participants