@@ -582,10 +582,14 @@ export class SyncDoc extends EventEmitter {
582
582
user_id : this . my_user_id ,
583
583
locs,
584
584
} ;
585
- if ( ! side_effect ) {
586
- x . time = this . client . server_time ( ) ;
585
+ const now = this . client . server_time ( ) ;
586
+ if ( ! side_effect || ( x . time ?? now ) >= now ) {
587
+ // the now comparison above is in case the cursor time
588
+ // is in the future (due to clock issues) -- always fix that.
589
+ x . time = now ;
587
590
}
588
591
if ( x . time != null ) {
592
+ // will actually always be non-null due to above
589
593
this . cursor_last_time = x . time ;
590
594
}
591
595
this . cursors_table . set ( x , "none" ) ;
@@ -1904,18 +1908,30 @@ export class SyncDoc extends EventEmitter {
1904
1908
) {
1905
1909
map = map . delete ( account_id ) ;
1906
1910
}
1907
- if ( maxAge ) {
1908
- // Remove any old cursors, where "old" is by default more than 1 minute old, since
1909
- // old cursors are not useful
1910
- const now = Date . now ( ) ;
1911
- for ( const [ client_id , value ] of map as any ) {
1912
- const time = value . get ( "time" ) ;
1911
+ // Remove any old cursors, where "old" is by default more than maxAge old.
1912
+ const now = Date . now ( ) ;
1913
+ for ( const [ client_id , value ] of map as any ) {
1914
+ const time = value . get ( "time" ) ;
1915
+ if ( time == null ) {
1916
+ // this should always be set.
1917
+ map = map . delete ( client_id ) ;
1918
+ continue ;
1919
+ }
1920
+ if ( maxAge ) {
1913
1921
// we use abs to implicitly exclude a bad value that is somehow in the future,
1914
1922
// if that were to happen.
1915
- if ( time == null || Math . abs ( now - time . valueOf ( ) ) >= maxAge ) {
1923
+ if ( Math . abs ( now - time . valueOf ( ) ) >= maxAge ) {
1916
1924
map = map . delete ( client_id ) ;
1925
+ continue ;
1917
1926
}
1918
1927
}
1928
+ if ( time >= now + 10 * 1000 ) {
1929
+ // We *always* delete any cursors more than 10 seconds in the future, since
1930
+ // that can only happen if a client inserts invalid data (e.g., clock not
1931
+ // yet synchronized). See https://github.com/sagemathinc/cocalc/issues/7969
1932
+ map = map . delete ( client_id ) ;
1933
+ continue ;
1934
+ }
1919
1935
}
1920
1936
return map ;
1921
1937
} ;
0 commit comments