---
title: Refresh configuration cache
summary: Initialize or refresh the in-memory Environment API payload on a throttled interval.
status: draft
owner: SAIF Framework
last_reviewed: 2026-07-30
library: SAIF.Framework.Security.EnvironmentApi
reference_type: package
operation_id: OP-ENV-002
trigger: Configuration-backed code accesses Configurations or GetConfigSettingInfo
---

# Refresh configuration cache

This operation keeps the library's shared `ConfigurationSettings` payload aligned with the Environment API without paying the cost of a network round trip on every configuration read. It throttles refresh checks to a configurable interval, reloads the full payload only when the server reports newer data, and updates the interval that governs future refresh checks.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-ENV-002 |
| **Trigger** | Configuration-backed operation touches `Configurations` or `GetConfigSettingInfo` |
| **Inputs** | Requested constructor sections, derived `ApplicationId`, derived `ApplicationHost` |
| **Outputs** | Populated or refreshed `ConfigurationSettings` cache and updated refresh interval |
| **Primary components** | `EnvironmentServiceBase.Configurations`, `EnvironmentServiceBase.RefreshConfigurationIfNewer`, `EnvironmentServiceBase.LastRefreshed`, `EnvironmentServiceBase.DoNewerSettingsExist` |
| **Entry point** | `SAIF.Framework.Security.EnvironmentApi\Services.Common\EnvironmentServiceBase.cs` |

## Steps

1. Read `LastRefreshed` to learn the newest timestamp the Environment API reports for this application's settings ([BR-002](../business-rules.md#br-002-environment-api-base-url-must-be-present)).
   - If no cache exists yet, seed `_lastRefreshChecked` and `_lastRefreshed` with `DateTime.Now` so the initial load can proceed without waiting on a prior check.
   - If the previous refresh check still falls within `AllowRefreshCheckInSeconds`, reuse the cached `_lastRefreshed` value instead of calling the service again — this is what keeps refresh checks cheap under load.
   - Otherwise call `/v2/settings/{ApplicationId}/lastRefreshed` and parse the returned timestamp.
2. Compare the service timestamp with `_configurations.LastLoaded` through `DoNewerSettingsExist`, and stop here when the cache already reflects the newest known data.
3. Build the settings URL that matches how this service instance was configured.
   - Use `/v2/settings/{ApplicationId}/{ApplicationHost}/value` when no sections were requested.
   - Use `/v2/settings/{ApplicationId}/{ApplicationHost}/{sections}/value?includeTrackSettings=true` when the constructor supplied one or more sections.
4. Download and deserialize the JSON payload into a new `ConfigurationSettings` instance ([BR-002](../business-rules.md#br-002-environment-api-base-url-must-be-present)).
5. Stamp `LastRefreshed` with the server value captured earlier and `LastLoaded` with the local current time, so subsequent staleness checks compare against this refresh.
6. Verify that the downloaded settings dictionary contains `checkforupdatedsettingsinseconds`. If the key is missing, throw `KeyNotFoundException` so refresh throttling can never silently fall back to an undefined interval ([BR-003](../business-rules.md#br-003-configuration-payload-must-declare-a-refresh-interval)).
7. Convert `checkforupdatedsettingsinseconds` to `int` and store it in `AllowRefreshCheckInSeconds` so it governs the next refresh check.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Configuration lookup needs cache]) --> LastRefreshed[Read LastRefreshed]
	LastRefreshed --> Reload{Cache missing or stale?}
	Reload -->|No| EndNo([Reuse current cache])
	Reload -->|Yes| Url[Build settings URL]
	Url --> Download[Download and deserialize payload]
	Download --> Check{Refresh interval key present?}
	Check -->|No| Fail([Throw KeyNotFoundException])
	Check -->|Yes| Save[Store cache and refresh interval]
	Save --> EndYes([Return refreshed cache])
```

## Failure and edge-case behavior

- A missing `EnvironmentApiUrl` environment variable throws before any HTTP request is issued.
- The initial `LastRefreshed` read uses local time when no cache exists yet, so the very first configuration access always proceeds without an extra round trip to check for staleness.
- The throttle interval is replaced by the freshly downloaded `checkforupdatedsettingsinseconds` value on every successful refresh, so operators can shorten or lengthen the interval by changing that setting alone.
- Configuration missing the refresh-interval key stops the operation with `KeyNotFoundException` rather than defaulting to a hidden interval.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [Configuration](../configuration.md)

## Sources
- SAIF.Framework.Security.EnvironmentApi\Services.Common\EnvironmentServiceBase.cs
