Repository navigation
topology: separate publication from lifecycle notifications - #6
Closed
dkropachev wants to merge 7 commits into
Closed
dkropachev wants to merge 7 commits into
dkropachev wants to merge 7 commits into
Conversation
Topology cleanup must retire missing hosts without retaining callback locks across policies or listeners. Otherwise a listener's synchronous refresh can deadlock against removal or let old cleanup overtake a newer Host with the same identity. Publish terminal state and queue ordered lifecycle work separately. Drain notifications without the coordination mutex and without recursive delivery. Reserve additions until ready, fence recovery by generation, and discard refresh snapshots overtaken by a newer accepted request. Keep DC/rack policy transitions ordered with their location changes and replace replica caches afterward. Document that refresh publishes the node list and token map synchronously, while notifications and location transitions can remain queued behind a running callback. Cover reentrant refresh, concurrent retirement, stale snapshots, custom policy callbacks, recovery reservations, location reversals and failures. Refs: scylladb#1007 Refs: scylladb#1036
Keep event admission, addition readiness, retirement and replacement ordering in the lifecycle coordinator so callers do not assemble partial transitions. Move queued DC/rack updates out of the control connection. Metadata still owns indexes and token maps; cluster and session code keep the policy, pool and connection operations. Preserve generation-based DOWN admission during metadata reindexing and exact-host checks for ADD and UP. Notification submission now consistently returns no result, whether delivery starts immediately or is deferred. Cover deferred admission, retirement during readiness reset and the notification return contract.
Close lifecycle admission before tearing down pools and executors. Drop queued notifications, clear pending host reservations, and cancel current or retired reconnectors without joining an active callback. A listener can shut down its cluster from an executor worker without joining itself. Keep UP and DOWN admission, completion flags and generation changes in the lifecycle coordinator. Make retirement idempotent and prevent late refresh results or pool completions from reviving closed lifecycle work. Cover callback-triggered shutdown, concurrent queue closure, late pool completion, repeated retirement and refresh results arriving after close.
Release ordinary failed ADD reservations so a healthy sibling pool cannot leave a session permanently unable to reconcile. Stop ADD preparation if its distance policy shuts down the cluster. Carry forced token rebuild intent into a newer accepted refresh while still discarding older topology data. Bind a stale candidate socket to its current observed host without republishing its snapshot, and reject a candidate whose route has since moved. Exercise these races and assert callback outcomes outside exception isolation. Clarify that executor teardown can still wait for workers even though closing lifecycle admission does not join callbacks.
Pass pool-failure ownership through policy callbacks as a reservation and recheck it atomically with DOWN admission. Releasing session and host locks before invoking policies avoids inversion with topology publication without letting a superseded failure mark the winning pool down. Retain all unfulfilled forced-refresh requests until a sufficiently new snapshot rebuilds tokens. Finish terminal retirement when shutdown races metadata replacement and cancel detached reconnectors during cleanup. Strengthen shutdown and UP/DOWN ownership tests with assertions outside callback exception handling and deterministic supersession scenarios.
Queue DOWN in the same publication transaction that claims its state. Deferring queue insertion until an executor worker starts lets a later UP overtake DOWN and leaves policy state out of sync with host health. Let the executor drain already-admitted lifecycle work while keeping the caller nonblocking. Remove unclaimed events if executor submission fails, and preserve acceptance if another drainer already claimed the event. Cover delayed executor delivery and rejected handoff cleanup.
Move lifecycle coordination, pool-failure reservations and their helpers into cassandra._lifecycle. Use ordinary class names within that private module and keep them out of the cluster module's public namespace. Declare no wildcard exports, avoid importing Cluster back into the lifecycle module, and preserve the existing cluster logging category. Update internal callers and tests without changing lifecycle behavior.
7 of 8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Alternative to scylladb#1036 for scylladb#1007. Missing-host reconciliation must retire hosts and clean up pools, policies, listeners, and reconnectors. Serializing the whole refresh across callbacks can deadlock when a listener calls synchronous refresh while another thread waits for that listener's host lock.
Publish topology changes in short transactions, then drain ordered lifecycle operations without topology or host callback locks. Check exact Host identity before stale queued work can take effect, reserve new hosts until their addition initializes, and discard refresh snapshots overtaken by a newer accepted refresh. Removal notifications precede replacement addition notifications; callback failures do not strand the queue.
This draft explores option 3 from the scylladb#1036 design discussion: separate publication and notification coordination instead of extending topology-first locking across lifecycle callbacks. The upstream PR remains unchanged.
Behavior and compatibility
refresh_nodes()synchronously publishes node-list and token metadata. If a lifecycle notification is already running, it can return before queued notifications finish. Pool availability can lag publication.Decisions
Refs scylladb#1007, scylladb#921, scylladb#1036.
Branch layout
Targets
dk/lifecycle-coordination-base, a snapshot of upstreammasterate152e3a11631f07b5ba0bb29b0f8c11e41b446ab. Forkmasteris behind upstream; the dedicated base keeps this diff limited to the alternative without updating forkmaster.Validation
cluster.pyandgit diff --checkpassed.Pre-review checklist
./docs/source/. This repository usesdocs/api/.Fixes:annotations to PR description. This fork draft references upstream issues without closing them.