Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit f471b28

Browse files
committed
Merge pull request #218 from github/fixes/203-message-bad
Fix race condition when finishing ui flows (PR #209 retargeting to master)
2 parents 6bdc154 + 95ef4f2 commit f471b28

File tree

7 files changed

+75
-19
lines changed

7 files changed

+75
-19
lines changed

src/GitHub.App/Controllers/UIController.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,9 @@ public IObservable<bool> ListenToCompletionState()
153153
void End(bool success)
154154
{
155155
uiProvider.RemoveService(typeof(IConnection));
156-
transition.OnCompleted();
157156
completion?.OnNext(success);
158157
completion?.OnCompleted();
159-
completion = null;
158+
transition.OnCompleted();
160159
}
161160

162161
void RunView(UIViewType viewType)

src/GitHub.Exports/Services/IUIProvider.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@ public interface IUIProvider : IServiceProvider
2424
IObservable<UserControl> SetupUI(UIControllerFlow controllerFlow, IConnection connection);
2525
void RunUI();
2626
void RunUI(UIControllerFlow controllerFlow, IConnection connection);
27+
IObservable<bool> ListenToCompletionState();
2728
}
2829
}

src/GitHub.VisualStudio/Services/UIProvider.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,19 @@ public IObservable<UserControl> SetupUI(UIControllerFlow controllerFlow, [AllowN
220220
return creation;
221221
}
222222

223+
public IObservable<bool> ListenToCompletionState()
224+
{
225+
var ui = currentUIFlow?.Value;
226+
if (ui == null)
227+
{
228+
log.Error("UIProvider:ListenToCompletionState:Cannot call ListenToCompletionState without calling SetupUI first");
229+
#if DEBUG
230+
throw new InvalidOperationException("Cannot call ListenToCompletionState without calling SetupUI first");
231+
#endif
232+
}
233+
return ui?.ListenToCompletionState() ?? Observable.Return(false);
234+
}
235+
223236
public void RunUI()
224237
{
225238
if (!Initialized)

src/GitHub.VisualStudio/TeamExplorer/Connect/GitHubConnectSection.cs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -330,14 +330,18 @@ void StartFlow(UIControllerFlow controllerFlow)
330330

331331
var uiProvider = ServiceProvider.GetExportedValue<IUIProvider>();
332332
uiProvider.GitServiceProvider = ServiceProvider;
333-
var ret = uiProvider.SetupUI(controllerFlow, SectionConnection);
334-
ret.Subscribe(_ => {}, () =>
335-
{
336-
if (controllerFlow == UIControllerFlow.Clone)
337-
isCloning = true;
338-
else if (controllerFlow == UIControllerFlow.Create)
339-
isCreating = true;
340-
});
333+
uiProvider.SetupUI(controllerFlow, SectionConnection);
334+
uiProvider.ListenToCompletionState()
335+
.Subscribe(success =>
336+
{
337+
if (success)
338+
{
339+
if (controllerFlow == UIControllerFlow.Clone)
340+
isCloning = true;
341+
else if (controllerFlow == UIControllerFlow.Create)
342+
isCreating = true;
343+
}
344+
});
341345
uiProvider.RunUI();
342346

343347
notifications.RemoveListener();

src/GitHub.VisualStudio/TeamExplorer/Sync/GitHubPublishSection.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,19 +118,20 @@ void ShowPublish()
118118
var ui = uiflow.Value;
119119
var creation = ui.SelectFlow(UIControllerFlow.Publish);
120120
bool success = false;
121-
ui.ListenToCompletionState().Subscribe(s => success = s, () =>
122-
{
123-
// there's no real cancel button in the publish form, but if support a back button there, then we want to hide the form
124-
IsVisible = false;
125-
if (success)
126-
ServiceProvider.TryGetService<ITeamExplorer>()?.NavigateToPage(new Guid(TeamExplorerPageIds.Home), null);
127-
});
121+
ui.ListenToCompletionState().Subscribe(s => success = s);
128122

129123
creation.Subscribe(c =>
130124
{
131125
SectionContent = c;
132126
c.DataContext = this;
133127
((IView)c).IsBusy.Subscribe(x => IsBusy = x);
128+
},
129+
() =>
130+
{
131+
// there's no real cancel button in the publish form, but if support a back button there, then we want to hide the form
132+
IsVisible = false;
133+
if (success)
134+
ServiceProvider.TryGetService<ITeamExplorer>()?.NavigateToPage(new Guid(TeamExplorerPageIds.Home), null);
134135
});
135136
ui.Start(null);
136137
}
@@ -142,9 +143,8 @@ protected override void Dispose(bool disposing)
142143
{
143144
if (!disposed)
144145
{
145-
if (disposable != null)
146-
disposable.Dispose();
147146
disposed = true;
147+
disposable?.Dispose();
148148
}
149149
}
150150
base.Dispose(disposing);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System;
2+
using System.ComponentModel.Composition;
3+
using System.Reactive.Linq;
4+
using System.Windows.Controls;
5+
using GitHub.Controllers;
6+
using GitHub.Models;
7+
using GitHub.Services;
8+
using GitHub.UI;
9+
using NSubstitute;
10+
using Xunit;
11+
using UnitTests;
12+
using GitHub.ViewModels;
13+
using ReactiveUI;
14+
using System.Collections.Generic;
15+
using GitHub.Authentication;
16+
using System.Collections.ObjectModel;
17+
using GitHub.VisualStudio;
18+
19+
public class UIProviderTests : TestBaseClass
20+
{
21+
[Fact]
22+
public void ListenToCompletionDoesNotThrowInRelease()
23+
{
24+
var provider = Substitutes.GetFullyMockedServiceProvider();
25+
26+
using (var p = new UIProvider(provider))
27+
{
28+
#if DEBUG
29+
Assert.ThrowsAny<InvalidOperationException>(() =>
30+
{
31+
#endif
32+
p.ListenToCompletionState();
33+
#if DEBUG
34+
});
35+
#endif
36+
}
37+
}
38+
}

src/UnitTests/UnitTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@
139139
<Compile Include="GitHub.Api\SimpleApiClientTests.cs" />
140140
<Compile Include="GitHub.App\Caches\CredentialCacheTests.cs" />
141141
<Compile Include="GitHub.App\Caches\ImageCacheTests.cs" />
142+
<Compile Include="GitHub.App\Controllers\UIProviderTests.cs" />
142143
<Compile Include="GitHub.App\Models\ModelServiceTests.cs" />
143144
<Compile Include="GitHub.App\Controllers\UIControllerTests.cs" />
144145
<Compile Include="GitHub.App\Models\PullRequestModelTests.cs" />

0 commit comments

Comments
 (0)