mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-09 16:24:45 +01:00
Fix agent host checkpoint file changes flicker (#324282)
Fix agent host file changes flicker Avoid recreating per-turn changeset subscriptions when equivalent session state updates produce equivalent URI objects. Add regression coverage for subscription stability. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
+3
-2
@@ -4,7 +4,8 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable } from '../../../../../../base/common/lifecycle.js';
|
||||
import { constObservable, derived, IObservable, observableFromEvent } from '../../../../../../base/common/observable.js';
|
||||
import { constObservable, derived, derivedOpts, IObservable, observableFromEvent } from '../../../../../../base/common/observable.js';
|
||||
import { isEqual } from '../../../../../../base/common/resources.js';
|
||||
import { isDefined } from '../../../../../../base/common/types.js';
|
||||
import { URI } from '../../../../../../base/common/uri.js';
|
||||
import { IAgentConnection } from '../../../../../../platform/agentHost/common/agentService.js';
|
||||
@@ -64,7 +65,7 @@ export class AgentHostResponseFileChangesProvider extends Disposable implements
|
||||
// the summary stays empty (and self-hidden) for them.
|
||||
const sessionStateObs = this._subscribe<SessionState>(StateComponents.Session, constObservable(backendSession));
|
||||
|
||||
const turnChangesetUriObs = derived(reader => {
|
||||
const turnChangesetUriObs = derivedOpts<URI | undefined>({ equalsFn: isEqual }, reader => {
|
||||
const sessionState = sessionStateObs.read(reader).read(reader);
|
||||
if (!sessionState || sessionState instanceof Error) {
|
||||
return undefined;
|
||||
|
||||
+24
@@ -22,14 +22,20 @@ class FakeAgentConnection extends mock<IAgentConnection>() {
|
||||
|
||||
private readonly _emitters = new Map<string, Emitter<unknown>>();
|
||||
private readonly _values = new Map<string, unknown>();
|
||||
private readonly _subscriptionCounts = new Map<string, number>();
|
||||
|
||||
setState(resource: string, value: unknown): void {
|
||||
this._values.set(resource, value);
|
||||
this._emitters.get(resource)?.fire(value);
|
||||
}
|
||||
|
||||
getSubscriptionCount(resource: string): number {
|
||||
return this._subscriptionCounts.get(resource) ?? 0;
|
||||
}
|
||||
|
||||
override getSubscription<T extends StateComponents>(_kind: T, resource: URI, _owner: string): IReference<IAgentSubscription<never>> {
|
||||
const key = resource.toString();
|
||||
this._subscriptionCounts.set(key, (this._subscriptionCounts.get(key) ?? 0) + 1);
|
||||
let emitter = this._emitters.get(key);
|
||||
if (!emitter) {
|
||||
emitter = new Emitter<unknown>();
|
||||
@@ -93,6 +99,24 @@ suite('AgentHostResponseFileChangesProvider', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
test('keeps the changeset subscription when session state updates', () => {
|
||||
const ds = store.add(new DisposableStore());
|
||||
const conn = new FakeAgentConnection();
|
||||
const provider = ds.add(new AgentHostResponseFileChangesProvider(conn, authority, () => backendSession));
|
||||
|
||||
conn.setState(backendSession.toString(), sessionStateWithTurnSupport());
|
||||
conn.setState(turnChangesetUri('t1'), { status: ChangesetStatus.Ready, files: [] } satisfies ChangesetState);
|
||||
observe(provider, ds);
|
||||
const subscriptionCountBeforeUpdate = conn.getSubscriptionCount(turnChangesetUri('t1'));
|
||||
|
||||
conn.setState(backendSession.toString(), sessionStateWithTurnSupport());
|
||||
|
||||
assert.deepStrictEqual([
|
||||
subscriptionCountBeforeUpdate,
|
||||
conn.getSubscriptionCount(turnChangesetUri('t1')),
|
||||
], [1, 1]);
|
||||
});
|
||||
|
||||
test('returns empty when the agent does not advertise a turn changeset', () => {
|
||||
const ds = store.add(new DisposableStore());
|
||||
const conn = new FakeAgentConnection();
|
||||
|
||||
Reference in New Issue
Block a user