(
row: ConnectionRow,
provider: CredentialProvider,
trigger: RefreshTrigger = "proactive",
)
| 2895 | ); |
| 2896 | |
| 2897 | const refreshConnectionToken = ( |
| 2898 | row: ConnectionRow, |
| 2899 | provider: CredentialProvider, |
| 2900 | trigger: RefreshTrigger = "proactive", |
| 2901 | ): Effect.Effect<string | null, StorageFailure | CredentialResolutionError> => |
| 2902 | // Share a single refresh per connection so concurrent resolves of the same |
| 2903 | // connection all await one refresh-token grant (the AS rotates the refresh |
| 2904 | // token; parallel grants would race on a consumed token — v1's refresh |
| 2905 | // deferred-map). The gate is cleared once the refresh settles so a later |
| 2906 | // expiry can refresh again. |
| 2907 | Effect.suspend(() => { |
| 2908 | const key = connectionKey(row); |
| 2909 | // Joining an in-flight grant is correct for BOTH triggers: whatever |
| 2910 | // that peer mints is newer than the token this fiber just saw rejected, |
| 2911 | // which is exactly what a reactive retry wants. The gate is cleared on |
| 2912 | // settle, so a 401 arriving after a refresh completed starts a fresh |
| 2913 | // grant rather than replaying a stale result. |
| 2914 | const existing = refreshInFlight.get(key); |
| 2915 | if (existing) return Deferred.await(existing); |
| 2916 | |
| 2917 | // The grant runs on a DETACHED fiber and every caller — including this |
| 2918 | // one — only awaits its deferred. The entry is shared across execution |
| 2919 | // stacks, so the fiber that registers it is merely the first arrival, |
| 2920 | // not an owner. Running the grant ON that fiber would hand it that |
| 2921 | // caller's interruption: a disconnected MCP client, an execution |
| 2922 | // deadline or a cancelled tool call would fail every peer awaiting the |
| 2923 | // same entry with an interrupt none of them caused and none can act on. |
| 2924 | // Awaiting is per-caller, so a cancelled peer detaches without touching |
| 2925 | // the grant or its siblings, and a grant nobody is left waiting on |
| 2926 | // still settles and still persists the rotated token — which is what |
| 2927 | // keeps the next caller off a consumed one. Token requests are bounded |
| 2928 | // by `AbortSignal.timeout`, so the detached fiber cannot outlive its |
| 2929 | // request. |
| 2930 | const deferred = Deferred.makeUnsafe< |
| 2931 | string | null, |
| 2932 | StorageFailure | CredentialResolutionError |
| 2933 | >(); |
| 2934 | // Nothing suspends between the lookup above and this registration, so |
| 2935 | // check-and-set is atomic against peer fibers and cannot double-fire. |
| 2936 | refreshInFlight.set(key, deferred); |
| 2937 | const run = performTokenRefresh(row, provider, trigger).pipe( |
| 2938 | Effect.exit, |
| 2939 | Effect.flatMap((exit) => Deferred.done(deferred, exit)), |
| 2940 | Effect.ensuring(Effect.sync(() => void refreshInFlight.delete(key))), |
| 2941 | ); |
| 2942 | return Effect.forkDetach(run).pipe(Effect.andThen(Deferred.await(deferred))); |
| 2943 | }); |
| 2944 | |
| 2945 | // Resolve every named input of a connection (`variable → value`). A |
| 2946 | // single-secret connection yields `{ token: <value> }`; an apiKey method with |
no test coverage detected