The base system wasn't bad to reason through but SHUTDOWN is where it gets messy.
First clarify the data structures and invariants (e.g., round-robin pointer, per-target connection lists, capacity tracking), then walk through the SHUTDOWN operation step-by-step: mark the target as removed, evict connections in insertion order, update capacity and round-robin state, and ensure thread safety. Discuss trade-offs like lazy vs eager cleanup and how to handle concurrent operations.
Pro tip: Mention that you would use a doubly-linked list for each target's connections to achieve O(1) eviction in insertion order, and a concurrent hash map for targets to avoid global locks. Also, consider idempotency and error handling for repeated SHUTDOWN calls.
Ask about concurrency, expected load, and whether SHUTDOWN is graceful or immediate. Confirm that eviction order is strictly insertion order and that the target is permanently removed.
Describe structures: a list of targets for round-robin (e.g., circular array or linked list), per-target connection queues (e.g., doubly-linked list for O(1) removal), and a map from target to its state (active/removed).
Outline steps: atomically mark target as removed to prevent new connections, then iterate its connection list in insertion order, closing each and updating global connection count. Finally, remove target from round-robin list and adjust the pointer if needed.
Discuss locking strategy: per-target locks for connection list and target state, and a global lock for round-robin list modifications. Ensure that in-flight connections are handled (e.g., wait for them to finish or force close).
Cover idempotency (repeated SHUTDOWN), target not found, empty connection list, and round-robin pointer adjustment. Compare eager vs lazy eviction and memory reclamation.
AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.