-
Notifications
You must be signed in to change notification settings - Fork 32
Fix/1.9.6 prod observations #168
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
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
2e206d1
fix(server): initialize _ping_timer to prevent AttributeError on thro…
anderslindho 0d64be9
fix(server): prevent NActive double-decrement after successful upload
anderslindho 4a7dd5f
fix(server): clamp NActive to zero in status log and metrics
anderslindho 40c1ba2
revert(server): restore global DeferredLock for CF commits
anderslindho c45191e
feat(server): add recceiver-clean CLI tool for manual channel sweeps
anderslindho 4ec9f7c
fix(server): orphan channel when last known IOC is absent in _handle_…
anderslindho e19a821
fix(server): evict IOC from memory when CF push exhausts retries
anderslindho 14325ec
refactor(server): move last-IOC None guard from _handle_channel_is_ol…
anderslindho a4f7245
refactor(server): reduce cognitive complexity of _handle_channels to 15
anderslindho File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
Large diffs are not rendered by default.
Oops, something went wrong.
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| """recceiver-clean — sweep Active CF channels to Inactive for a given recceiver ID. | ||
|
|
||
| Run after a RecCeiver restart (with cleanOnStart=False) to mark channels Inactive | ||
| whose IOCs have not reconnected. | ||
|
|
||
| Usage: | ||
| recceiver-clean -f /path/to/recceiver.conf [--recceiver-id ID] [--dry-run] | ||
| """ | ||
|
|
||
| import argparse | ||
| import configparser | ||
| import logging | ||
| import sys | ||
|
|
||
| from requests import RequestException | ||
|
|
||
| from recceiver.cf.adapter import PyCFClientAdapter | ||
| from recceiver.cf.config import CFConfig | ||
| from recceiver.cf.model import CFProperty, CFPropertyName, PVStatus | ||
| from recceiver.processors import ConfigAdapter | ||
|
|
||
| log = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| def run_clean(cf_config: CFConfig, client=None, dry_run: bool = False) -> int: | ||
| """Mark all Active channels for cf_config.recceiver_id Inactive. | ||
|
|
||
| Returns the total count of channels swept. Pass a pre-built client for testing. | ||
| """ | ||
| if client is None: | ||
| from channelfinder import ChannelFinderClient | ||
|
|
||
| client = PyCFClientAdapter( | ||
|
anderslindho marked this conversation as resolved.
|
||
| ChannelFinderClient( | ||
| BaseURL=cf_config.base_url, | ||
| username=cf_config.cf_username, | ||
| password=cf_config.cf_password, | ||
| verify_ssl=cf_config.verify_ssl, | ||
| ), | ||
| size_limit=int(cf_config.cf_query_limit), | ||
| ) | ||
|
anderslindho marked this conversation as resolved.
|
||
|
|
||
| total = 0 | ||
| # find_active_for_recceiver is paginated (bounded by size_limit). In live mode each | ||
| # update_property call marks the current page Inactive, so the next query returns a | ||
| # fresh batch; the loop drains all pages. In dry-run mode nothing is deactivated so | ||
| # the same batch would come back on every iteration — break after the first page. | ||
| while True: | ||
|
anderslindho marked this conversation as resolved.
|
||
| channels = client.find_active_for_recceiver(cf_config.recceiver_id) | ||
| if not channels: | ||
| break | ||
| log.info( | ||
| "Found %d active channels for recceiver_id=%r%s", | ||
| len(channels), | ||
| cf_config.recceiver_id, | ||
| " (dry-run)" if dry_run else "", | ||
| ) | ||
| if not dry_run: | ||
| client.update_property( | ||
| CFProperty(CFPropertyName.PV_STATUS.value, cf_config.username, PVStatus.INACTIVE.value), | ||
| [ch.name for ch in channels], | ||
| ) | ||
| total += len(channels) | ||
| if dry_run: | ||
| break | ||
|
anderslindho marked this conversation as resolved.
|
||
| return total | ||
|
|
||
|
|
||
| def main(argv=None): | ||
| parser = argparse.ArgumentParser(description="Mark active CF channels Inactive for a given recceiver ID.") | ||
| parser.add_argument("-f", "--config", required=True, help="Path to recceiver config file") | ||
| parser.add_argument("--recceiver-id", default=None, help="Override recceiver ID from config") | ||
| parser.add_argument("--dry-run", action="store_true", help="Print count without modifying CF") | ||
| args = parser.parse_args(argv) | ||
|
|
||
| logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") | ||
|
|
||
| conf = configparser.ConfigParser() | ||
| conf.read(args.config) | ||
| cf_conf = CFConfig.loads(ConfigAdapter(conf, "cf")) | ||
|
|
||
| if args.recceiver_id: | ||
| cf_conf.recceiver_id = args.recceiver_id | ||
|
|
||
| if cf_conf.base_url is None: | ||
| print("ERROR: baseUrl must be configured in [cf] section", file=sys.stderr) | ||
| sys.exit(1) | ||
|
|
||
| try: | ||
| count = run_clean(cf_conf, dry_run=args.dry_run) | ||
| except RequestException as err: | ||
| print(f"ERROR: CF request failed: {err}", file=sys.stderr) | ||
| sys.exit(2) | ||
|
|
||
| action = "Would mark" if args.dry_run else "Marked" | ||
| print(f"{action} {count} channels Inactive for recceiver_id={cf_conf.recceiver_id!r}") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.