mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 13:00:58 +00:00
Fix #89817
This commit is contained in:
parent
45a1ac9982
commit
19b7657634
|
@ -54,7 +54,8 @@ export abstract class AbstractSynchroniser extends Disposable {
|
|||
}
|
||||
|
||||
async hasRemoteData(): Promise<boolean> {
|
||||
const remoteUserData = await this.getRemoteUserData();
|
||||
const lastSyncData = await this.getLastSyncUserData();
|
||||
const remoteUserData = await this.getRemoteUserData(lastSyncData);
|
||||
return remoteUserData.content !== null;
|
||||
}
|
||||
|
||||
|
@ -77,11 +78,8 @@ export abstract class AbstractSynchroniser extends Disposable {
|
|||
await this.fileService.writeFile(this.lastSyncResource, VSBuffer.fromString(JSON.stringify(lastSyncUserData)));
|
||||
}
|
||||
|
||||
protected async getRemoteUserData(lastSyncData?: IUserData | null): Promise<IUserData> {
|
||||
if (lastSyncData === undefined) {
|
||||
lastSyncData = await this.getLastSyncUserData();
|
||||
}
|
||||
return this.userDataSyncStoreService.read(this.getRemoteDataResourceKey(), lastSyncData || null, this.source);
|
||||
protected async getRemoteUserData(lastSyncData: IUserData | null): Promise<IUserData> {
|
||||
return this.userDataSyncStoreService.read(this.getRemoteDataResourceKey(), lastSyncData, this.source);
|
||||
}
|
||||
|
||||
protected async updateRemoteUserData(content: string, ref: string | null): Promise<string> {
|
||||
|
|
|
@ -206,7 +206,6 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse
|
|||
}
|
||||
|
||||
if (added.length || removed.length || updated.length) {
|
||||
this.logService.info('Extensions: Updating local extensions...');
|
||||
skippedExtensions = await this.updateLocalExtensions(added, removed, updated, skippedExtensions);
|
||||
}
|
||||
|
||||
|
@ -218,7 +217,7 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse
|
|||
remoteUserData = { ref, content };
|
||||
}
|
||||
|
||||
if (hasChanges || !lastSyncUserData) {
|
||||
if (lastSyncUserData?.ref !== remoteUserData.ref) {
|
||||
// update last sync
|
||||
this.logService.info('Extensions: Updating last synchronised extensions...');
|
||||
await this.updateLastSyncUserData<ILastSyncUserData>({ ...remoteUserData, skippedExtensions });
|
||||
|
|
|
@ -195,7 +195,7 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs
|
|||
remoteUserData = { ref, content };
|
||||
}
|
||||
|
||||
if (hasChanges || !lastSyncUserData) {
|
||||
if (lastSyncUserData?.ref !== remoteUserData.ref) {
|
||||
// update last sync
|
||||
this.logService.info('UI State: Updating last synchronised ui state...');
|
||||
await this.updateLastSyncUserData(remoteUserData);
|
||||
|
|
|
@ -29,6 +29,7 @@ interface ISyncContent {
|
|||
interface ISyncPreviewResult {
|
||||
readonly fileContent: IFileContent | null;
|
||||
readonly remoteUserData: IUserData;
|
||||
readonly lastSyncUserData: IUserData | null;
|
||||
readonly hasLocalChanged: boolean;
|
||||
readonly hasRemoteChanged: boolean;
|
||||
readonly hasConflicts: boolean;
|
||||
|
@ -63,7 +64,8 @@ export class KeybindingsSynchroniser extends AbstractFileSynchroniser implements
|
|||
this.logService.info('Keybindings: Started pulling keybindings...');
|
||||
this.setStatus(SyncStatus.Syncing);
|
||||
|
||||
const remoteUserData = await this.getRemoteUserData();
|
||||
const lastSyncUserData = await this.getLastSyncUserData();
|
||||
const remoteUserData = await this.getRemoteUserData(lastSyncUserData);
|
||||
const remoteContent = remoteUserData.content !== null ? this.getKeybindingsContentFromSyncContent(remoteUserData.content) : null;
|
||||
|
||||
if (remoteContent !== null) {
|
||||
|
@ -74,7 +76,8 @@ export class KeybindingsSynchroniser extends AbstractFileSynchroniser implements
|
|||
hasConflicts: false,
|
||||
hasLocalChanged: true,
|
||||
hasRemoteChanged: false,
|
||||
remoteUserData
|
||||
remoteUserData,
|
||||
lastSyncUserData
|
||||
}));
|
||||
await this.apply();
|
||||
}
|
||||
|
@ -106,14 +109,16 @@ export class KeybindingsSynchroniser extends AbstractFileSynchroniser implements
|
|||
const fileContent = await this.getLocalFileContent();
|
||||
|
||||
if (fileContent !== null) {
|
||||
const remoteUserData = await this.getRemoteUserData();
|
||||
const lastSyncUserData = await this.getLastSyncUserData();
|
||||
const remoteUserData = await this.getRemoteUserData(lastSyncUserData);
|
||||
await this.fileService.writeFile(this.environmentService.settingsSyncPreviewResource, fileContent.value);
|
||||
this.syncPreviewResultPromise = createCancelablePromise(() => Promise.resolve<ISyncPreviewResult>({
|
||||
fileContent,
|
||||
hasConflicts: false,
|
||||
hasLocalChanged: false,
|
||||
hasRemoteChanged: true,
|
||||
remoteUserData
|
||||
remoteUserData,
|
||||
lastSyncUserData
|
||||
}));
|
||||
await this.apply(undefined, true);
|
||||
}
|
||||
|
@ -204,7 +209,8 @@ export class KeybindingsSynchroniser extends AbstractFileSynchroniser implements
|
|||
const preview = await this.syncPreviewResultPromise;
|
||||
content = preview.remoteUserData?.content;
|
||||
} else {
|
||||
const remoteUserData = await this.getRemoteUserData();
|
||||
const lastSyncData = await this.getLastSyncUserData();
|
||||
const remoteUserData = await this.getRemoteUserData(lastSyncData);
|
||||
content = remoteUserData.content;
|
||||
}
|
||||
return content ? this.getKeybindingsContentFromSyncContent(content) : null;
|
||||
|
@ -247,6 +253,8 @@ export class KeybindingsSynchroniser extends AbstractFileSynchroniser implements
|
|||
return;
|
||||
}
|
||||
|
||||
let { fileContent, remoteUserData, lastSyncUserData, hasLocalChanged, hasRemoteChanged } = await this.syncPreviewResultPromise;
|
||||
|
||||
if (content === undefined) {
|
||||
if (await this.fileService.exists(this.environmentService.keybindingsSyncPreviewResource)) {
|
||||
const keybindingsPreivew = await this.fileService.readFile(this.environmentService.keybindingsSyncPreviewResource);
|
||||
|
@ -261,25 +269,21 @@ export class KeybindingsSynchroniser extends AbstractFileSynchroniser implements
|
|||
throw error;
|
||||
}
|
||||
|
||||
let { fileContent, remoteUserData, hasLocalChanged, hasRemoteChanged } = await this.syncPreviewResultPromise;
|
||||
if (!hasLocalChanged && !hasRemoteChanged) {
|
||||
this.logService.trace('Keybindings: No changes found during synchronizing keybindings.');
|
||||
}
|
||||
|
||||
if (hasLocalChanged) {
|
||||
this.logService.info('Keybindings: Updating local keybindings');
|
||||
await this.updateLocalFileContent(content, fileContent);
|
||||
}
|
||||
|
||||
if (hasRemoteChanged) {
|
||||
this.logService.info('Keybindings: Updating remote keybindings');
|
||||
const remoteContents = this.updateSyncContent(content, remoteUserData.content);
|
||||
const ref = await this.updateRemoteUserData(remoteContents, forcePush ? null : remoteUserData.ref);
|
||||
remoteUserData = { ref, content: remoteContents };
|
||||
}
|
||||
if (remoteUserData?.content) {
|
||||
this.logService.info('Keybindings: Updating last synchronised keybindings');
|
||||
const lastSyncContent = this.updateSyncContent(content, null);
|
||||
await this.updateLastSyncUserData({ ref: remoteUserData.ref, content: lastSyncContent });
|
||||
}
|
||||
|
||||
// Delete the preview
|
||||
await this.fileService.del(this.environmentService.keybindingsSyncPreviewResource);
|
||||
|
@ -287,6 +291,12 @@ export class KeybindingsSynchroniser extends AbstractFileSynchroniser implements
|
|||
this.logService.trace('Keybindings: No changes found during synchronizing keybindings.');
|
||||
}
|
||||
|
||||
if (lastSyncUserData?.ref !== remoteUserData.ref && (content !== undefined || fileContent !== null)) {
|
||||
this.logService.info('Keybindings: Updating last synchronised keybindings');
|
||||
const lastSyncContent = this.updateSyncContent(content !== undefined ? content : fileContent!.value.toString(), null);
|
||||
await this.updateLastSyncUserData({ ref: remoteUserData.ref, content: lastSyncContent });
|
||||
}
|
||||
|
||||
this.syncPreviewResultPromise = null;
|
||||
}
|
||||
|
||||
|
@ -304,9 +314,9 @@ export class KeybindingsSynchroniser extends AbstractFileSynchroniser implements
|
|||
}
|
||||
|
||||
private async generatePreview(token: CancellationToken): Promise<ISyncPreviewResult> {
|
||||
const lastSyncData = await this.getLastSyncUserData();
|
||||
const lastSyncContent = lastSyncData && lastSyncData.content ? this.getKeybindingsContentFromSyncContent(lastSyncData.content) : null;
|
||||
const remoteUserData = await this.getRemoteUserData(lastSyncData);
|
||||
const lastSyncUserData = await this.getLastSyncUserData();
|
||||
const lastSyncContent = lastSyncUserData && lastSyncUserData.content ? this.getKeybindingsContentFromSyncContent(lastSyncUserData.content) : null;
|
||||
const remoteUserData = await this.getRemoteUserData(lastSyncUserData);
|
||||
const remoteContent = remoteUserData.content ? this.getKeybindingsContentFromSyncContent(remoteUserData.content) : null;
|
||||
// Get file content last to get the latest
|
||||
const fileContent = await this.getLocalFileContent();
|
||||
|
@ -319,7 +329,7 @@ export class KeybindingsSynchroniser extends AbstractFileSynchroniser implements
|
|||
const localContent: string = fileContent ? fileContent.value.toString() : '[]';
|
||||
if (this.hasErrors(localContent)) {
|
||||
this.logService.error('Keybindings: Unable to sync keybindings as there are errors/warning in keybindings file.');
|
||||
return { fileContent, remoteUserData, hasLocalChanged, hasRemoteChanged, hasConflicts };
|
||||
return { fileContent, remoteUserData, lastSyncUserData, hasLocalChanged, hasRemoteChanged, hasConflicts };
|
||||
}
|
||||
|
||||
if (!lastSyncContent // First time sync
|
||||
|
@ -350,7 +360,7 @@ export class KeybindingsSynchroniser extends AbstractFileSynchroniser implements
|
|||
await this.fileService.writeFile(this.environmentService.keybindingsSyncPreviewResource, VSBuffer.fromString(previewContent));
|
||||
}
|
||||
|
||||
return { fileContent, remoteUserData, hasLocalChanged, hasRemoteChanged, hasConflicts };
|
||||
return { fileContent, remoteUserData, lastSyncUserData, hasLocalChanged, hasRemoteChanged, hasConflicts };
|
||||
}
|
||||
|
||||
private _formattingOptions: Promise<FormattingOptions> | undefined = undefined;
|
||||
|
|
|
@ -25,6 +25,7 @@ import { AbstractFileSynchroniser } from 'vs/platform/userDataSync/common/abstra
|
|||
interface ISyncPreviewResult {
|
||||
readonly fileContent: IFileContent | null;
|
||||
readonly remoteUserData: IUserData;
|
||||
readonly lastSyncUserData: IUserData | null;
|
||||
readonly hasLocalChanged: boolean;
|
||||
readonly hasRemoteChanged: boolean;
|
||||
readonly remoteContent: string | null;
|
||||
|
@ -84,7 +85,8 @@ export class SettingsSynchroniser extends AbstractFileSynchroniser implements IS
|
|||
this.logService.info('Settings: Started pulling settings...');
|
||||
this.setStatus(SyncStatus.Syncing);
|
||||
|
||||
const remoteUserData = await this.getRemoteUserData();
|
||||
const lastSyncUserData = await this.getLastSyncUserData();
|
||||
const remoteUserData = await this.getRemoteUserData(lastSyncUserData);
|
||||
|
||||
if (remoteUserData.content !== null) {
|
||||
const fileContent = await this.getLocalFileContent();
|
||||
|
@ -101,6 +103,7 @@ export class SettingsSynchroniser extends AbstractFileSynchroniser implements IS
|
|||
hasRemoteChanged: false,
|
||||
remoteContent: content,
|
||||
remoteUserData,
|
||||
lastSyncUserData,
|
||||
}));
|
||||
|
||||
await this.apply();
|
||||
|
@ -136,7 +139,8 @@ export class SettingsSynchroniser extends AbstractFileSynchroniser implements IS
|
|||
// Remove ignored settings
|
||||
const content = updateIgnoredSettings(fileContent.value.toString(), '{}', getIgnoredSettings(this.configurationService), formatUtils);
|
||||
await this.fileService.writeFile(this.environmentService.settingsSyncPreviewResource, VSBuffer.fromString(content));
|
||||
const remoteUserData = await this.getRemoteUserData();
|
||||
const lastSyncUserData = await this.getLastSyncUserData();
|
||||
const remoteUserData = await this.getRemoteUserData(lastSyncUserData);
|
||||
|
||||
this.syncPreviewResultPromise = createCancelablePromise(() => Promise.resolve<ISyncPreviewResult>({
|
||||
conflictSettings: [],
|
||||
|
@ -146,6 +150,7 @@ export class SettingsSynchroniser extends AbstractFileSynchroniser implements IS
|
|||
hasRemoteChanged: true,
|
||||
remoteContent: content,
|
||||
remoteUserData,
|
||||
lastSyncUserData,
|
||||
}));
|
||||
|
||||
await this.apply(undefined, true);
|
||||
|
@ -213,7 +218,8 @@ export class SettingsSynchroniser extends AbstractFileSynchroniser implements IS
|
|||
const preview = await this.syncPreviewResultPromise;
|
||||
content = preview.remoteUserData?.content;
|
||||
} else {
|
||||
const remoteUserData = await this.getRemoteUserData();
|
||||
const lastSyncData = await this.getLastSyncUserData();
|
||||
const remoteUserData = await this.getRemoteUserData(lastSyncData);
|
||||
content = remoteUserData.content;
|
||||
}
|
||||
return content !== undefined ? content : null;
|
||||
|
@ -294,7 +300,7 @@ export class SettingsSynchroniser extends AbstractFileSynchroniser implements IS
|
|||
return;
|
||||
}
|
||||
|
||||
let { fileContent, remoteUserData, hasLocalChanged, hasRemoteChanged } = await this.syncPreviewResultPromise;
|
||||
let { fileContent, remoteUserData, lastSyncUserData, hasLocalChanged, hasRemoteChanged } = await this.syncPreviewResultPromise;
|
||||
|
||||
if (content === undefined) {
|
||||
if (await this.fileService.exists(this.environmentService.settingsSyncPreviewResource)) {
|
||||
|
@ -332,7 +338,7 @@ export class SettingsSynchroniser extends AbstractFileSynchroniser implements IS
|
|||
this.logService.trace('Settings: No changes found during synchronizing settings.');
|
||||
}
|
||||
|
||||
if (remoteUserData.content) {
|
||||
if (lastSyncUserData?.ref !== remoteUserData.ref) {
|
||||
this.logService.info('Settings: Updating last synchronised settings');
|
||||
await this.updateLastSyncUserData(remoteUserData);
|
||||
}
|
||||
|
@ -354,8 +360,8 @@ export class SettingsSynchroniser extends AbstractFileSynchroniser implements IS
|
|||
}
|
||||
|
||||
private async generatePreview(resolvedConflicts: { key: string, value: any }[], token: CancellationToken): Promise<ISyncPreviewResult> {
|
||||
const lastSyncData = await this.getLastSyncUserData();
|
||||
const remoteUserData = await this.getRemoteUserData(lastSyncData);
|
||||
const lastSyncUserData = await this.getLastSyncUserData();
|
||||
const remoteUserData = await this.getRemoteUserData(lastSyncUserData);
|
||||
// Get file content last to get the latest
|
||||
const fileContent = await this.getLocalFileContent();
|
||||
let hasLocalChanged: boolean = false;
|
||||
|
@ -376,7 +382,7 @@ export class SettingsSynchroniser extends AbstractFileSynchroniser implements IS
|
|||
else {
|
||||
this.logService.trace('Settings: Merging remote settings with local settings...');
|
||||
const formatUtils = await this.getFormattingOptions();
|
||||
const result = merge(localContent, remoteUserData.content, lastSyncData ? lastSyncData.content : null, getIgnoredSettings(this.configurationService), resolvedConflicts, formatUtils);
|
||||
const result = merge(localContent, remoteUserData.content, lastSyncUserData ? lastSyncUserData.content : null, getIgnoredSettings(this.configurationService), resolvedConflicts, formatUtils);
|
||||
hasConflicts = result.hasConflicts;
|
||||
hasLocalChanged = result.localContent !== null;
|
||||
hasRemoteChanged = result.remoteContent !== null;
|
||||
|
@ -399,7 +405,7 @@ export class SettingsSynchroniser extends AbstractFileSynchroniser implements IS
|
|||
}
|
||||
|
||||
this.setConflicts(conflictSettings);
|
||||
return { fileContent, remoteUserData, hasLocalChanged, hasRemoteChanged, remoteContent, conflictSettings, hasConflicts };
|
||||
return { fileContent, remoteUserData, lastSyncUserData, hasLocalChanged, hasRemoteChanged, remoteContent, conflictSettings, hasConflicts };
|
||||
}
|
||||
|
||||
private _formattingOptions: Promise<FormattingOptions> | undefined = undefined;
|
||||
|
|
|
@ -125,13 +125,17 @@ export class UserDataAutoSync extends Disposable implements IUserDataAutoSyncSer
|
|||
this.successiveFailures = 0;
|
||||
}
|
||||
|
||||
triggerAutoSync(): Promise<void> {
|
||||
return this.syncDelayer.trigger(() => {
|
||||
this.logService.info('Sync: Triggerred.');
|
||||
return this.sync(false, true);
|
||||
}, this.successiveFailures
|
||||
? 1000 * 1 * Math.min(this.successiveFailures, 60) /* Delay by number of seconds as number of failures up to 1 minute */
|
||||
: 1000);
|
||||
async triggerAutoSync(): Promise<void> {
|
||||
if (this.enabled) {
|
||||
return this.syncDelayer.trigger(() => {
|
||||
this.logService.info('Sync: Triggerred.');
|
||||
return this.sync(false, true);
|
||||
}, this.successiveFailures
|
||||
? 1000 * 1 * Math.min(this.successiveFailures, 60) /* Delay by number of seconds as number of failures up to 1 minute */
|
||||
: 1000);
|
||||
} else {
|
||||
this.syncDelayer.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue