1811
1812
async subscribe(resource: URI, clientId: string): Promise<IStateSnapshot> {
1813
>
this._logService.trace(`[AgentService] subscribe: ${resource.toString()}`);
agentService.ts
1814
>
const resourceStr = resource.toString();
1815
>
// Register the subscriber up front so a concurrent unsubscribe cannot
1816
>
// evict the session state while we are awaiting restore. On any failure
1817
>
// path below we must roll the registration back, otherwise the leaked
1818
>
// refcount would permanently pin (or block eviction of) the resource.
1819
>
// {@link addSubscriber} is the single point that triggers the
1820
>
// uncommitted-changeset refresh on the 0→1 transition (covers both
1821
>
// the cold-snapshot path here and the handshake fast-path used by
1822
>
// {@link ProtocolServerHandler} when state is already cached).
1823
>
this.addSubscriber(resource, clientId);
1824
>
try {
1825
>
// Check for terminal state
1826
>
const terminalState = this._terminalManager.getTerminalState(resourceStr);
1827
>
if (terminalState) {
1828
return { resource: resourceStr, state: terminalState, fromSeq: this._stateManager.serverSeq };
1829
}
1831
>
let snapshot = this._stateManager.getSnapshot(resourceStr);
1832
>
const parsedChangeset = parseChangesetUri(resourceStr);
1833
>
if (snapshot && parsedChangeset && !this._stateManager.getSessionState(parsedChangeset.sessionUri)) {
1834
await this._changesetCoordinator.restoreSessionIfChangesetSubscription(resource, s => this.restoreSession(s));
1835
snapshot = this._stateManager.getSnapshot(resourceStr);
1836
}
1838
// Chat channel URIs carry their owning session URI. The chat
1839
// snapshot only materializes once that session is restored