Skip to content

Simplify the code for synchronizing the workspace with OOP.#61634

Merged
CyrusNajmabadi merged 8 commits intodotnet:mainfrom
CyrusNajmabadi:synchronizeSimplification
Jun 1, 2022
Merged

Simplify the code for synchronizing the workspace with OOP.#61634
CyrusNajmabadi merged 8 commits intodotnet:mainfrom
CyrusNajmabadi:synchronizeSimplification

Conversation

@CyrusNajmabadi
Copy link
Copy Markdown
Contributor

No description provided.

@ghost ghost added the Area-IDE label Jun 1, 2022
{
private readonly Workspace _workspace;
private readonly TaskQueue _textChangeQueue;
private readonly AsyncQueue<IAsyncToken> _workQueue = new();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prior system used queues without any ability for batching/debouncing. New system can do that.

/// <summary>
/// Cancellation token we trigger when we enter the paused state.
/// </summary>
private CancellationToken _currentWorkToken;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pausing is controlled by a very simple cancellation-series.

protected override async Task ExecuteAsync()
public void Shutdown()
{
lock (_gate)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for locks.

private SolutionChecksumUpdater? _checksumUpdater;
#pragma warning disable IDE0044 // Add readonly modifier
private CancellationTokenSource _disposalCancellationSource = new();
#pragma warning restore IDE0044 // Add readonly modifier
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no clue why this wasn't readonly.

var state = await oldDocument.State.GetStateChecksumsAsync(cancellationToken).ConfigureAwait(false);

await client.TryInvokeAsync<IRemoteAssetSynchronizationService>(
(service, cancellationToken) => service.SynchronizeTextAsync(oldDocument.Id, state.Text, textChanges, cancellationToken),
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could consider an entrypoint that actually takes all the docIds and the set of text changes all at once

@CyrusNajmabadi CyrusNajmabadi marked this pull request as ready for review June 1, 2022 17:50
@CyrusNajmabadi CyrusNajmabadi requested a review from a team as a code owner June 1, 2022 17:50
_workspace = workspace;
_textChangeQueue = new TaskQueue(Listener, TaskScheduler.Default);

_textChangeQueue = new AsyncBatchingWorkQueue<(Document? oldDocument, Document? newDocument)>(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I see we have two queues because there are two different calls to synchronize the primary workspace and synchronize text changes. So question...

My naive implementation would be to just have one call that says 'SynchronizePrimaryWorkspace' that gives it the tree? of checksums, which the remote host can then diff against what it has and callback asking for what it is missing. However I'm guessing that could be expensive in the common case when one document is just changing over and over. Is that roughly a correct understanding?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talked offline. The reason for the text-syncing is to optimize teh common case of lots of edits happening to a file. We can just preemptively populate oop with teh contents of those docs just by sending the text changes over.

@CyrusNajmabadi CyrusNajmabadi enabled auto-merge June 1, 2022 18:21
public SolutionChecksumUpdater(Workspace workspace, IGlobalOptionService globalOptions, IAsynchronousOperationListenerProvider listenerProvider, CancellationToken shutdownToken)
: base(listenerProvider.GetListener(FeatureAttribute.SolutionChecksumUpdater),
workspace.Services.GetService<IGlobalOperationNotificationService>(),
TimeSpan.FromMilliseconds(globalOptions.GetOption(RemoteHostOptions.SolutionChecksumMonitorBackOffTimeSpanInMS)), shutdownToken)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SolutionChecksumMonitorBackOffTimeSpanInMS

Can this option now be deleted?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. thanks.

Comment on lines +105 to +110
// An expensive global operation started (like a build). Pause ourselves and cancel any outstanding work in
// progress to synchronize the solution.
//
// Note: We purposefully ignore the cancellation token produced by CreateNext. The purpose here is to
// cancel the token controlling the current work, but not have any uncanceled token for new work to use when
// it comes in.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you get a sense if this really does much? I have a internal perf bug that was hinting that we might be doing lots of sync operations when we are competing against other work. But even this means we're not preemptively doing a sync, any individual feature could still force the sync to happen anyways in response to any other operation, correct?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's a very good question. perhaps this pausing was done to prevent many syncs from happening as things like DLLs changed on disk underneath the IDE as you're doing a build. the benefit being that sure, featuers might request this, but they are also going at their slow cadence. at we aren't aggressively pushing here in that case.

but a part of me does feel like this is pretty suspect and potentially not at all beneficial.

@CyrusNajmabadi CyrusNajmabadi merged commit 9722863 into dotnet:main Jun 1, 2022
@ghost ghost added this to the Next milestone Jun 1, 2022
@RikkiGibson RikkiGibson modified the milestones: Next, 17.3 P3 Jun 28, 2022
@CyrusNajmabadi CyrusNajmabadi deleted the synchronizeSimplification branch July 1, 2022 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants