diff --git a/docs/Deployment/Database/schema.md b/docs/Deployment/Database/schema.md index 66f194f0d..ef2bf9118 100644 --- a/docs/Deployment/Database/schema.md +++ b/docs/Deployment/Database/schema.md @@ -18,9 +18,15 @@ The diagrams below illustrates the database schema and relationships for MPS and datetime lastconnected datetime lastseen datetime lastdisconnected + int powerstate + int ospowersavingstate + datetime powerstateupdatedat } ``` +The nullable `powerstate` and `ospowersavingstate` fields store the last successfully cached device observations. `powerstateupdatedat` records the read start time as PostgreSQL `timestamp with time zone`. The device API exposes these as `powerState`, `osPowerSavingState`, and `powerStateUpdatedAt`. The background refresher, successful live power-state reads, and successful reads following power actions can populate these fields. An unavailable optional OS power-saving state is stored as `0` (unknown). Failed primary reads preserve the previous values and timestamp. Writes with an older read-start timestamp are ignored, and disconnecting retains the last-known observation. Consumers should check the timestamp when assessing freshness. + +Existing PostgreSQL databases require the [power-state cache migration](../upgradeVersion.md#upgrade-to-mps-with-the-device-power-state-cache) before upgrading MPS. ### RPS ```mermaid erDiagram diff --git a/docs/Deployment/upgradeVersion.md b/docs/Deployment/upgradeVersion.md index 42fa737a6..6e154a065 100644 --- a/docs/Deployment/upgradeVersion.md +++ b/docs/Deployment/upgradeVersion.md @@ -5,6 +5,40 @@ Every deployment environment is unique. The prerequisites and setup steps provided here serve as general guidance for running the latest published images. Please ensure you follow your organization’s internal deployment, security, and validation procedures when upgrading or updating your environment. +### Upgrade to MPS with the device power-state cache + +Before starting an MPS version that includes the device power-state cache, existing PostgreSQL deployments must add the cache columns to the `devices` table in `mpsdb`. + +!!! important "Apply the migration before upgrading MPS" + These columns are required even when `power_state_refresh_interval` is `0` (background refresh disabled), because device queries include the cache fields. `data/initMPS.sql` defines these columns for fresh installations only; it contains no `ALTER TABLE` migration for an existing table. Apply this migration before starting any upgraded MPS instance. + +1. Connect to the MPS database using a database user with permission to alter the `devices` table. + + ```sh + psql -h [HOSTNAME] -p 5432 -d mpsdb -U [DATABASE USER] + ``` + +2. Add the nullable cache columns. The statement can be run again safely because each column uses `IF NOT EXISTS`. + + ```sql title="mpsdb - Add device power-state cache columns" + ALTER TABLE devices + ADD COLUMN IF NOT EXISTS powerstate integer, + ADD COLUMN IF NOT EXISTS ospowersavingstate integer, + ADD COLUMN IF NOT EXISTS powerstateupdatedat timestamp with time zone; + ``` + +3. Verify that all three columns are present. + + ```text + \d devices + ``` + +4. Continue with the [minor version upgrade](#upgrade-a-minor-version-ie-2x-to-2y) steps below. + +Fresh PostgreSQL databases initialized with the updated `data/initMPS.sql` already include these columns. MongoDB deployments do not require this SQL migration; the cache fields are added on the first successful cache write. + +Existing device rows retain their data, and the new fields remain null until the first successful cache write. With the refresher feature installed, a background refresh, a successful live power-state read, or a successful read following a power action can populate them. Disabling background refresh does not disable updates from live reads or power actions. See [MPS configuration](../Reference/MPS/configuration.md#device-power-state-cache) for refresh settings and [the database schema](Database/schema.md#mps) for cache fields. + ### Upgrade to 2.28 (Sep 25) from 2.18 (Dec 23) or later The 2.28 release of DMT Cloud Deployment requires updates to the `rpsdb` database. If upgrading from **2.18 (Dec 23)** or any later version, run the following SQL scripts to add or modify tables before continuing with the upgrade diff --git a/docs/Reference/MPS/configuration.md b/docs/Reference/MPS/configuration.md index 0d8e358b3..e01b4a2a1 100644 --- a/docs/Reference/MPS/configuration.md +++ b/docs/Reference/MPS/configuration.md @@ -43,4 +43,26 @@ The `.env` variables set have priority and overwrite the corresponding `.mpsrc` | MPS_CONSUL_PORT | consul_port | `8500` | Consul Port to listen on | | MPS_CONSUL_KEY_PREFIX | consul_key_prefix | `MPS` | Default prefix key for Consul data structure | +### Device power-state cache +MPS refreshes the cached power state of connected devices when their CIRA keepalives arrive and the refresh interval has elapsed. The device API returns `powerState`, `osPowerSavingState`, and `powerStateUpdatedAt` as server-owned fields. They describe the last successfully cached observation. `powerStateUpdatedAt` records when that read started, not when the device changed state or the database write completed. A failed background refresh leaves the cached values and timestamp unchanged. + +| `.env` Variable Name | `.mpsrc` Variable Name | Default | Description | +| :--- | :--- | :--- | :--- | +| MPS_POWER_STATE_REFRESH_INTERVAL | power_state_refresh_interval | `300` | Minimum delay in seconds after a successful background refresh before another becomes eligible. Set to `0` to disable background refresh; otherwise use an integer from `30` to `86400`. | +| MPS_POWER_STATE_REFRESH_JITTER | power_state_refresh_jitter | `60` | Maximum initial delay in seconds after a device connects. Use a nonnegative integer. The first keepalive after this delay makes the device eligible for refresh. | +| MPS_POWER_STATE_MAX_CONCURRENT | power_state_max_concurrent | `20` | Maximum concurrent background device reads per MPS process. Use an integer from `1` to `500`. | + +For ordinary failures, the retry delay doubles with each consecutive failure, up to 64 times the refresh interval, with a maximum delay of 24 hours. The 24-hour limit caps the delay between retries; it does not stop retries after 24 hours of failures. A successful refresh resets the failure count. With the default interval, retry delays are 10, 20, 40, 80, 160, and 320 minutes, then 320 minutes for subsequent failures. + +In the current implementation, a request timeout suspends background refresh for that connection until the device reconnects. Disconnecting clears the retry state. Disconnected devices are not refreshed, and reconnecting starts a new initial delay. + +Existing PostgreSQL deployments must apply the [cache migration](../../Deployment/upgradeVersion.md#upgrade-to-mps-with-the-device-power-state-cache) before starting the upgraded MPS service, including when background refresh is disabled. + +Successful live reads through `GET /api/v1/amt/power/state/:guid` also update the cache. MPS sends the live response first, then attempts the cache write; cache-write exceptions are logged without changing the response. After a standard power action returns AMT success (`ReturnValue = 0`), or an OS power-saving-state change succeeds, MPS sends the action response and then reads and caches the actual device state. An OS action that finds the device already in the requested state does not trigger another read. The requested action itself is never used as the cached state, and the device may still be transitioning when the follow-up read occurs. + +These route-triggered updates remain enabled when `power_state_refresh_interval` is `0`. They do not reset the background schedule, retry count, or timeout suspension. The process-wide concurrency setting limits background reads; route-triggered reads share the existing per-device limiter. + +The optional OS power-saving-state read falls back to `0` (unknown) on ordinary failure. A timeout on this read suspends the background refresher until reconnect, while the live and post-action paths use `0` and can still cache a successful primary power-state reading. Failed primary reads do not update the cache. + +PostgreSQL and MongoDB reject cache writes with a read-start timestamp older than the stored timestamp. Because route-triggered cache writes occur after the HTTP response, an immediate device-list request can still return the previous observation. The Sample UI loads the list before fetching live states, so its displayed state can differ from the earlier list response. Use `powerStateUpdatedAt` to assess freshness; live and cached responses are not guaranteed to match at every instant.