Skip to content

Persist per-channel HLS server selection across sxm.pl restarts#76

Draft
Copilot wants to merge 3 commits intomainfrom
copilot/add-last-server-to-channel-cache
Draft

Persist per-channel HLS server selection across sxm.pl restarts#76
Copilot wants to merge 3 commits intomainfrom
copilot/add-last-server-to-channel-cache

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 4, 2026

When sxm.pl restarts, the per-channel CDN server selection (primary/secondary) was lost, causing channels that had failed over to secondary to reset unnecessarily. This persists the server selection to a dedicated lightweight file (server_state.json) so it survives restarts and is always current.

Changes

  • New save_server_state(): Writes only the channel_server hash to server_state.json in the same cache directory. Called immediately inside switch_channel_server() and reset_channel_server() so the file always reflects the current state — not just at the 24-hour channel cache refresh.
  • New load_server_state(): Reads and restores channel_server on startup. Backward-compatible — silently skips if the file does not exist yet (e.g. first run or upgrade from an older version).
  • Startup: load_server_state() is called at startup alongside load_channel_cache().
  • channels.json unchanged: Server state is no longer embedded in the channel list cache.
# Written on every server switch/reset (switch_channel_server / reset_channel_server):
sub save_server_state {
    my $state = { channel_server => $self->{channel_server} || {} };
    # writes {"channel_server":{"ch1":"primary","ch2":"secondary"}} to server_state.json
}

# Called at startup:
sub load_server_state {
    # restores $self->{channel_server} from server_state.json if it exists
}
Original prompt

Enhance Plugins/SiriusXM/Bin/sxm.pl so that the currently selected server is saved along with the existing channel cache data, and restored when the script is restarted. This will persist the server selection across reloads without creating new files or data structures—just add a key (such as last_server) to the cached data structure used for channels. Be sure to save the server info when writing channel data to cache, and read it when loading the channel cache on restart.

Requirements:

  • Do not create a new file or top-level variable solely for this purpose. Use the same structure and file currently used for caching channels.
  • Code should add a key for the current server to the persisted data, save it at the same time as channel data, and use it to restore the server selection on startup.
  • Changes should be documented in comments where appropriate.
  • Follow existing style and standards used in sxm.pl.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: What is the best way to remember which server we are currently using between reloads of sxm.pl

Assistant: The best way to persistently remember which server you are currently using between reloads of sxm.pl is to store the server selection in a persistent location that survives process restarts. Common approaches include:

1. Configuration File

Store the server information in a configuration file (e.g., server_state.conf, last_server.txt, or in the main config file).

  • On startup, read the server name or address from this file.
  • When the server changes, update the file with the new server selection.

Sample Perl logic:

# To read the last used server:
my $server_file = 'last_server.txt';
my $current_server;
if (open my $fh, '<', $server_file) {
    chomp($current_server = <$fh>);
    close $fh;
}

# To write/update the current server:
open my $fh, '>', $server_file or die "Can't write: $!";
print $fh $current_server;
close $fh;

2. Environment Variable (Not Persistent)

Setting an environment variable (e.g., $ENV{SIRIUSXM_SERVER}) will only keep the value for the current shell or process session. This is not persistent across reloads, so not suitable unless you use a wrapper script that always sets this variable on startup.

3. Database/Key-Value Store

If the plugin already uses a database or a key-value store for other state, record the current server there.

4. Command-Line Argument (Not Persistent)

You could require specifying the server with each start, but this is manual and not automatic.


Recommendation:
For simple use cases, a dedicated small text file (last_server.txt) is usually the easiest and most portable solution. It avoids race conditions, is simple to implement, works across platforms, and requires no dependencies.

Let me know if you want a code snippet customized for your exact logic, or if your sxm.pl setup already uses a config system that should be leveraged!

User: we already are caching channel data and loading at restart, perhaps just save and load it there.

Assistant: That’s a great idea! If your sxm.pl script already serializes and reloads channel data at startup/shutdown (using, for example, a cache file like a JSON, YAML, or Perl Storable), the cleanest solution is to add the current server to the same persistent data structure.

Steps

  1. When you write out cached channel data, also save the current server information (e.g., as a new key in the serialized hash).
  2. On restart, when you restore or load the cached channel data, extract the server information along with it and use it to pre-select or default to the previous server.

Example

Suppose you currently have code like this for storing channel cache (in Perl pseudo-code):

my %cache = (
    channels => $channels_arrayref,
    # ... other data ...
);
# Save:
store \%cache, "channel_cache.storable";

Just expand this to include the server:

# When saving:
$cache{last_server} = $current_server;
store \%cache, "channel_cache.storable";

# When loading:
my $cache_ref = retrieve("channel_cache.storable");
my $last_server = $cache_ref->{last_server}; # Use this as your default on startup

If using JSON or YAML, do the same—just add a key/value pair for the server.

Advantages

  • No new files. Keeps related state together.
  • Ensures correct pairing. The cached channels correspond to the last-used server.
  • Minimal code refactor.

Conclusion:
Saving and restoring the current server information along with your existing channel cache data is the most cohesive and robust approach. Just add a field like last_server (or active_server) to your cached data structure.

If you want a concrete code patch, just tell me the format you use for the cache (Storable, JSON, etc.) and I’ll provide a patch!

User: Just assign an agent to this task please

Assistant: To proceed and assign an agen...

This pull request was created from Copilot chat.

Copilot AI changed the title [WIP] Enhance sxm.pl to persist selected server across reloads Persist per-channel HLS server selection across sxm.pl restarts Apr 4, 2026
Copilot AI requested a review from paul-1 April 4, 2026 18:24
@paul-1
Copy link
Copy Markdown
Owner

paul-1 commented Apr 4, 2026

@copilot When is the cache file updated? Looks like only when the channel data is refreshed. However we could have changed servers in the meantime. We need to update the data when the server change is made. However the channel cache is quite large to be writing for the server change. Perhaps a separate file with the last_server is better.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 4, 2026

@copilot When is the cache file updated? Looks like only when the channel data is refreshed. However we could have changed servers in the meantime. We need to update the data when the server chang...

Good catch. The channel cache is indeed only written during the 24-hour refresh cycle, so embedding server state there means switches that happen between refreshes would be lost on restart.

Switched to a dedicated lightweight server_state.json file in the same cache directory (commit 226ee64):

  • save_server_state() is called immediately inside switch_channel_server() and reset_channel_server(), so the file always reflects the current state.
  • load_server_state() is called at startup alongside load_channel_cache() to restore channel_server.
  • The channel cache (channels.json) is unchanged — no channel_server key there anymore.
  • The new file is tiny (just {"channel_server":{"ch1":"primary","ch2":"secondary"}}), so writing it on every switch is negligible.

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.

2 participants