MCPcopy
hub / github.com/simstudioai/sim / poll

Function poll

apps/sim/lib/core/config/appconfig.ts:65–123  ·  view source on GitHub ↗

* Run one AppConfig poll for `entry`: starts a session if no token is held, then * calls `GetLatestConfiguration`. An empty payload means "unchanged" (or an * unseeded profile) and the previous value is kept. Any error is logged and the * last good value is retained. Marks the entry `loaded` on a

(
  ids: AppConfigProfileIdentifiers,
  parse: (json: unknown) => T,
  entry: CacheEntry<T>
)

Source from the content-addressed store, hash-verified

63 * don't poll faster than the server allows (which would throttle).
64 */
65async function poll<T>(
66 ids: AppConfigProfileIdentifiers,
67 parse: (json: unknown) => T,
68 entry: CacheEntry<T>
69): Promise<T | null> {
70 let response: GetLatestConfigurationCommandOutput
71 try {
72 const dataClient = getClient()
73
74 if (!entry.nextToken) {
75 const session = await dataClient.send(
76 new StartConfigurationSessionCommand({
77 ApplicationIdentifier: ids.application,
78 EnvironmentIdentifier: ids.environment,
79 ConfigurationProfileIdentifier: ids.profile,
80 })
81 )
82 entry.nextToken = session.InitialConfigurationToken
83 }
84
85 response = await dataClient.send(
86 new GetLatestConfigurationCommand({ ConfigurationToken: entry.nextToken })
87 )
88 entry.nextToken = response.NextPollConfigurationToken ?? entry.nextToken
89 } catch (error) {
90 // Network/session failure: drop the token so the next attempt starts a fresh
91 // session (handles expired or invalid tokens). Mark loaded + back off so we
92 // serve the fallback and retry in the background rather than blocking every
93 // request during an outage.
94 entry.nextToken = undefined
95 entry.expiresAt = Date.now() + DEFAULT_TTL_MS
96 entry.loaded = true
97 logger.error('AppConfig fetch failed; serving last known value', {
98 profile: cacheKey(ids),
99 error: getErrorMessage(error),
100 })
101 return entry.value
102 }
103
104 // Parse outside the network try: a decode/parse error must NOT discard the
105 // already-rotated session token — the round trip succeeded, so the next poll
106 // can reuse it instead of opening a new session. Keep the last good value.
107 try {
108 if (response.Configuration && response.Configuration.length > 0) {
109 const text = new TextDecoder().decode(response.Configuration)
110 entry.value = parse(JSON.parse(text))
111 }
112 } catch (error) {
113 logger.error('AppConfig response parse failed; serving last known value', {
114 profile: cacheKey(ids),
115 error: getErrorMessage(error),
116 })
117 }
118
119 const intervalMs = (response.NextPollIntervalInSeconds ?? 60) * 1000
120 entry.expiresAt = Date.now() + Math.max(DEFAULT_TTL_MS, intervalMs)
121 entry.loaded = true
122 return entry.value

Callers 1

fetchAppConfigProfileFunction · 0.85

Calls 7

getErrorMessageFunction · 0.90
cacheKeyFunction · 0.85
sendMethod · 0.80
errorMethod · 0.80
parseMethod · 0.80
getClientFunction · 0.70
parseFunction · 0.50

Tested by

no test coverage detected