66import { Delayer , disposableTimeout , CancelablePromise , createCancelablePromise , timeout } from 'vs/base/common/async' ;
77import { Event , Emitter } from 'vs/base/common/event' ;
88import { Disposable , toDisposable , MutableDisposable , IDisposable } from 'vs/base/common/lifecycle' ;
9- import { IUserDataSyncLogService , IUserDataSyncService , IUserDataAutoSyncService , UserDataSyncError , UserDataSyncErrorCode , IUserDataSyncResourceEnablementService , IUserDataSyncStoreService , UserDataAutoSyncError , ISyncTask } from 'vs/platform/userDataSync/common/userDataSync' ;
9+ import { IUserDataSyncLogService , IUserDataSyncService , IUserDataAutoSyncService , UserDataSyncError , UserDataSyncErrorCode , IUserDataSyncResourceEnablementService , IUserDataSyncStoreService , UserDataAutoSyncError , ISyncTask , IUserDataSyncStoreManagementService } from 'vs/platform/userDataSync/common/userDataSync' ;
1010import { IUserDataSyncAccountService } from 'vs/platform/userDataSync/common/userDataSyncAccount' ;
1111import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry' ;
1212import { isPromiseCanceledError } from 'vs/base/common/errors' ;
@@ -16,6 +16,8 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
1616import { IUserDataSyncMachinesService } from 'vs/platform/userDataSync/common/userDataSyncMachines' ;
1717import { localize } from 'vs/nls' ;
1818import { toLocalISOString } from 'vs/base/common/date' ;
19+ import { URI } from 'vs/base/common/uri' ;
20+ import { isEqual } from 'vs/base/common/resources' ;
1921
2022type AutoSyncClassification = {
2123 sources : { classification : 'SystemMetaData' , purpose : 'FeatureInsight' , isMeasurement : true } ;
@@ -41,7 +43,8 @@ export class UserDataAutoSyncEnablementService extends Disposable {
4143
4244 constructor (
4345 @IStorageService protected readonly storageService : IStorageService ,
44- @IEnvironmentService private readonly environmentService : IEnvironmentService
46+ @IEnvironmentService private readonly environmentService : IEnvironmentService ,
47+ @IUserDataSyncStoreManagementService protected readonly userDataSyncStoreManagementService : IUserDataSyncStoreManagementService
4548 ) {
4649 super ( ) ;
4750 this . _register ( storageService . onDidChangeStorage ( e => this . onDidStorageChange ( e ) ) ) ;
@@ -58,7 +61,7 @@ export class UserDataAutoSyncEnablementService extends Disposable {
5861 }
5962
6063 canToggleEnablement ( ) : boolean {
61- return this . environmentService . sync === undefined ;
64+ return this . userDataSyncStoreManagementService . userDataSyncStore !== undefined && this . environmentService . sync === undefined ;
6265 }
6366
6467 private onDidStorageChange ( workspaceStorageChangeEvent : IWorkspaceStorageChangeEvent ) : void {
@@ -83,7 +86,21 @@ export class UserDataAutoSyncService extends UserDataAutoSyncEnablementService i
8386 private readonly _onError : Emitter < UserDataSyncError > = this . _register ( new Emitter < UserDataSyncError > ( ) ) ;
8487 readonly onError : Event < UserDataSyncError > = this . _onError . event ;
8588
89+ private lastSyncUrl : URI | undefined ;
90+ private get syncUrl ( ) : URI | undefined {
91+ const value = this . storageService . get ( storeUrlKey , StorageScope . GLOBAL ) ;
92+ return value ? URI . parse ( value ) : undefined ;
93+ }
94+ private set syncUrl ( syncUrl : URI | undefined ) {
95+ if ( syncUrl ) {
96+ this . storageService . store ( storeUrlKey , syncUrl . toString ( ) , StorageScope . GLOBAL ) ;
97+ } else {
98+ this . storageService . remove ( storeUrlKey , StorageScope . GLOBAL ) ;
99+ }
100+ }
101+
86102 constructor (
103+ @IUserDataSyncStoreManagementService userDataSyncStoreManagementService : IUserDataSyncStoreManagementService ,
87104 @IUserDataSyncStoreService private readonly userDataSyncStoreService : IUserDataSyncStoreService ,
88105 @IUserDataSyncResourceEnablementService private readonly userDataSyncResourceEnablementService : IUserDataSyncResourceEnablementService ,
89106 @IUserDataSyncService private readonly userDataSyncService : IUserDataSyncService ,
@@ -94,13 +111,12 @@ export class UserDataAutoSyncService extends UserDataAutoSyncEnablementService i
94111 @IStorageService storageService : IStorageService ,
95112 @IEnvironmentService environmentService : IEnvironmentService
96113 ) {
97- super ( storageService , environmentService ) ;
114+ super ( storageService , environmentService , userDataSyncStoreManagementService ) ;
98115 this . syncTriggerDelayer = this . _register ( new Delayer < void > ( 0 ) ) ;
116+ this . lastSyncUrl = this . syncUrl ;
117+ this . syncUrl = userDataSyncStoreManagementService . userDataSyncStore ?. url ;
99118
100- if ( userDataSyncStoreService . userDataSyncStore ) {
101-
102- storageService . store ( storeUrlKey , userDataSyncStoreService . userDataSyncStore . url . toString ( ) , StorageScope . GLOBAL ) ;
103-
119+ if ( userDataSyncStoreManagementService . userDataSyncStore ) {
104120 if ( this . isEnabled ( ) ) {
105121 this . logService . info ( 'Auto Sync is enabled.' ) ;
106122 } else {
@@ -123,7 +139,7 @@ export class UserDataAutoSyncService extends UserDataAutoSyncEnablementService i
123139 const { enabled, message } = this . isAutoSyncEnabled ( ) ;
124140 if ( enabled ) {
125141 if ( this . autoSync . value === undefined ) {
126- this . autoSync . value = new AutoSync ( 1000 * 60 * 5 /* 5 miutes */ , this . userDataSyncStoreService , this . userDataSyncService , this . userDataSyncMachinesService , this . logService , this . storageService ) ;
142+ this . autoSync . value = new AutoSync ( this . lastSyncUrl , 1000 * 60 * 5 /* 5 miutes */ , this . userDataSyncStoreManagementService , this . userDataSyncStoreService , this . userDataSyncService , this . userDataSyncMachinesService , this . logService , this . storageService ) ;
127143 this . autoSync . value . register ( this . autoSync . value . onDidStartSync ( ( ) => this . lastSyncTriggerTime = new Date ( ) . getTime ( ) ) ) ;
128144 this . autoSync . value . register ( this . autoSync . value . onDidFinishSync ( e => this . onDidFinishSync ( e ) ) ) ;
129145 if ( this . startAutoSync ( ) ) {
@@ -164,6 +180,7 @@ export class UserDataAutoSyncService extends UserDataAutoSyncEnablementService i
164180
165181 async turnOn ( ) : Promise < void > {
166182 this . stopDisableMachineEventually ( ) ;
183+ this . lastSyncUrl = this . syncUrl ;
167184 this . setEnablement ( true ) ;
168185 }
169186
@@ -228,7 +245,7 @@ export class UserDataAutoSyncService extends UserDataAutoSyncEnablementService i
228245 }
229246
230247 // Turned off from another device
231- if ( userDataSyncError . code === UserDataSyncErrorCode . TurnedOff ) {
248+ else if ( userDataSyncError . code === UserDataSyncErrorCode . TurnedOff ) {
232249 await this . turnOff ( false , true /* force soft turnoff on error */ ) ;
233250 this . logService . info ( 'Auto Sync: Turned off sync because sync is turned off in the cloud' ) ;
234251 }
@@ -261,6 +278,13 @@ export class UserDataAutoSyncService extends UserDataAutoSyncEnablementService i
261278 this . logService . info ( 'Auto Sync: Turned off sync because server has {0} content with older version than of client. Requires server reset.' , userDataSyncError . resource ) ;
262279 }
263280
281+ // Endpoint changed
282+ else if ( userDataSyncError . code === UserDataSyncErrorCode . ServiceChanged ) {
283+ await this . turnOff ( false , true /* force soft turnoff on error */ , true /* do not disable machine */ ) ;
284+ await this . turnOn ( ) ;
285+ this . logService . info ( 'Auto Sync: Endpoint changed. Turned off auto sync, reset local state and turned on auto sync.' ) ;
286+ }
287+
264288 else {
265289 this . logService . error ( userDataSyncError ) ;
266290 this . successiveFailures ++ ;
@@ -342,7 +366,9 @@ class AutoSync extends Disposable {
342366 private syncPromise : CancelablePromise < void > | undefined ;
343367
344368 constructor (
369+ private readonly lastSyncUrl : URI | undefined ,
345370 private readonly interval : number /* in milliseconds */ ,
371+ private readonly userDataSyncStoreManagementService : IUserDataSyncStoreManagementService ,
346372 private readonly userDataSyncStoreService : IUserDataSyncStoreService ,
347373 private readonly userDataSyncService : IUserDataSyncService ,
348374 private readonly userDataSyncMachinesService : IUserDataSyncMachinesService ,
@@ -407,14 +433,24 @@ class AutoSync extends Disposable {
407433
408434 // Server has no data but this machine was synced before
409435 if ( manifest === null && await this . userDataSyncService . hasPreviouslySynced ( ) ) {
410- // Sync was turned off in the cloud
411- throw new UserDataAutoSyncError ( localize ( 'turned off' , "Cannot sync because syncing is turned off in the cloud" ) , UserDataSyncErrorCode . TurnedOff ) ;
436+ if ( ! this . lastSyncUrl || isEqual ( this . lastSyncUrl , this . userDataSyncStoreManagementService . userDataSyncStore ?. url ) ) {
437+ // Sync was turned off in the cloud
438+ throw new UserDataAutoSyncError ( localize ( 'turned off' , "Cannot sync because syncing is turned off in the cloud" ) , UserDataSyncErrorCode . TurnedOff ) ;
439+ } else {
440+ // Sync endpoint changed
441+ throw new UserDataAutoSyncError ( localize ( 'endpoint changed' , "Cannot sync because sync endpoint is changed" ) , UserDataSyncErrorCode . ServiceChanged ) ;
442+ }
412443 }
413444
414445 const sessionId = this . storageService . get ( sessionIdKey , StorageScope . GLOBAL ) ;
415446 // Server session is different from client session
416447 if ( sessionId && manifest && sessionId !== manifest . session ) {
417- throw new UserDataAutoSyncError ( localize ( 'session expired' , "Cannot sync because current session is expired" ) , UserDataSyncErrorCode . SessionExpired ) ;
448+ if ( ! this . lastSyncUrl || isEqual ( this . lastSyncUrl , this . userDataSyncStoreManagementService . userDataSyncStore ?. url ) ) {
449+ throw new UserDataAutoSyncError ( localize ( 'session expired' , "Cannot sync because current session is expired" ) , UserDataSyncErrorCode . SessionExpired ) ;
450+ } else {
451+ // Sync endpoint changed
452+ throw new UserDataAutoSyncError ( localize ( 'endpoint changed' , "Cannot sync because sync endpoint is changed" ) , UserDataSyncErrorCode . ServiceChanged ) ;
453+ }
418454 }
419455
420456 const machines = await this . userDataSyncMachinesService . getMachines ( manifest || undefined ) ;
0 commit comments