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

Make it easier to add new usage metrics. #1130

Merged
merged 11 commits into from
Nov 17, 2017
6 changes: 4 additions & 2 deletions src/GitHub.App/Models/RepositoryHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ public IObservable<AuthenticationResult> LogInFromCache()
{
var user = await loginManager.LoginFromCache(Address, ApiClient.GitHubClient);
var accountCacheItem = new AccountCacheItem(user);
usage.IncrementLoginCount().Forget();

await usage.IncrementCounter(x => x.NumberOfLogins);
await ModelService.InsertUser(accountCacheItem);

if (user != null)
Expand Down Expand Up @@ -107,7 +108,8 @@ public IObservable<AuthenticationResult> LogIn(string usernameOrEmail, string pa
{
var user = await loginManager.Login(Address, ApiClient.GitHubClient, usernameOrEmail, password);
var accountCacheItem = new AccountCacheItem(user);
usage.IncrementLoginCount().Forget();

await usage.IncrementCounter(x => x.NumberOfLogins);
await ModelService.InsertUser(accountCacheItem);

if (user != null)
Expand Down
2 changes: 1 addition & 1 deletion src/GitHub.App/Services/PullRequestService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ async Task<IPullRequestModel> PushAndCreatePR(IRepositoryHost host,
await Task.Delay(TimeSpan.FromSeconds(5));

var ret = await host.ModelService.CreatePullRequest(sourceRepository, targetRepository, sourceBranch, targetBranch, title, body);
await usageTracker.IncrementUpstreamPullRequestCount();
await usageTracker.IncrementCounter(x => x.NumberOfUpstreamPullRequests);
return ret;
}

Expand Down
2 changes: 1 addition & 1 deletion src/GitHub.App/Services/RepositoryCloneService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public async Task CloneRepository(
try
{
await vsGitServices.Clone(cloneUrl, path, true, progress);
await usageTracker.IncrementCloneCount();
await usageTracker.IncrementCounter(x => x.NumberOfClones);
}
catch (Exception ex)
{
Expand Down
2 changes: 1 addition & 1 deletion src/GitHub.App/ViewModels/GistCreationViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ IObservable<Gist> OnCreateGist(object unused)
newGist.Files.Add(FileName, SelectedText);

return gistPublishService.PublishGist(apiClient, newGist)
.Do(_ => usageTracker.IncrementCreateGistCount().Forget())
.Do(_ => usageTracker.IncrementCounter(x => x.NumberOfGists).Forget())
.Catch<Gist, Exception>(ex =>
{
if (!ex.IsCriticalException())
Expand Down
26 changes: 22 additions & 4 deletions src/GitHub.App/ViewModels/PullRequestDetailViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ public async Task Load(string remoteRepositoryOwner, IPullRequestModel pullReque

if (firstLoad)
{
usageTracker.IncrementPullRequestOpened().Forget();
usageTracker.IncrementCounter(x => x.NumberOfPullRequestsOpened).Forget();
}

if (!isInCheckout)
Expand Down Expand Up @@ -604,19 +604,37 @@ IObservable<Unit> DoCheckout(object unused)
.GetDefaultLocalBranchName(LocalRepository, Model.Number, Model.Title)
.SelectMany(x => pullRequestsService.Checkout(LocalRepository, Model, x));
}
}).Do(_ => usageTracker.IncrementPullRequestCheckOutCount(IsFromFork).Forget());
}).Do(_ =>
{
if (IsFromFork)
usageTracker.IncrementCounter(x => x.NumberOfForkPullRequestsCheckedOut).Forget();
else
usageTracker.IncrementCounter(x => x.NumberOfLocalPullRequestsCheckedOut).Forget();
});
}

IObservable<Unit> DoPull(object unused)
{
return pullRequestsService.Pull(LocalRepository)
.Do(_ => usageTracker.IncrementPullRequestPullCount(IsFromFork).Forget());
.Do(_ =>
{
if (IsFromFork)
usageTracker.IncrementCounter(x => x.NumberOfForkPullRequestPulls).Forget();
else
usageTracker.IncrementCounter(x => x.NumberOfLocalPullRequestPulls).Forget();
});
}

IObservable<Unit> DoPush(object unused)
{
return pullRequestsService.Push(LocalRepository)
.Do(_ => usageTracker.IncrementPullRequestPushCount(IsFromFork).Forget());
.Do(_ =>
{
if (IsFromFork)
usageTracker.IncrementCounter(x => x.NumberOfForkPullRequestPushes).Forget();
else
usageTracker.IncrementCounter(x => x.NumberOfLocalPullRequestPushes).Forget();
});
}

class CheckoutCommandState : IPullRequestCheckoutState
Expand Down
2 changes: 1 addition & 1 deletion src/GitHub.App/ViewModels/RepositoryCreationViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ IObservable<Unit> OnCreateRepository(object state)
SelectedAccount,
BaseRepositoryPath,
repositoryHost.ApiClient)
.Do(_ => usageTracker.IncrementCreateCount().Forget());
.Do(_ => usageTracker.IncrementCounter(x => x.NumberOfReposCreated).Forget());
}

ReactiveCommand<Unit> InitializeCreateRepositoryCommand()
Expand Down
2 changes: 1 addition & 1 deletion src/GitHub.App/ViewModels/RepositoryPublishViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ IObservable<ProgressState> OnPublishRepository(object arg)
var account = SelectedAccount;

return repositoryPublishService.PublishRepository(newRepository, account, SelectedHost.ApiClient)
.Do(_ => usageTracker.IncrementPublishCount().Forget())
.Do(_ => usageTracker.IncrementCounter(x => x.NumberOfReposPublished).Forget())
.Select(_ => ProgressState.Success)
.Catch<ProgressState, Exception>(ex =>
{
Expand Down
2 changes: 2 additions & 0 deletions src/GitHub.Exports/GitHub.Exports.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@
<Compile Include="Models\ICommentModel.cs" />
<Compile Include="Models\IInlineCommentModel.cs" />
<Compile Include="Models\IPullRequestReviewCommentModel.cs" />
<Compile Include="Models\UsageData.cs" />
<Compile Include="Services\IUsageService.cs" />
<Compile Include="Settings\PkgCmdID.cs" />
<Compile Include="ViewModels\IHasErrorState.cs" />
<Compile Include="ViewModels\IHasLoading.cs" />
Expand Down
20 changes: 20 additions & 0 deletions src/GitHub.Exports/Models/UsageData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;

namespace GitHub.Models
{
/// <summary>
/// Wraps a <see cref="UsageModel"/> with a <see cref="LastUpdated"/> field.
/// </summary>
public class UsageData
{
/// <summary>
/// Gets or sets the last update time.
/// </summary>
public DateTimeOffset LastUpdated { get; set; }

/// <summary>
/// Gets the model containing the current usage data.
/// </summary>
public UsageModel Model { get; set; }
}
}
54 changes: 20 additions & 34 deletions src/GitHub.Exports/Models/UsageModel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Reflection;

namespace GitHub.Models
{
Expand Down Expand Up @@ -39,41 +40,26 @@ public class UsageModel

public UsageModel Clone(bool includeWeekly, bool includeMonthly)
{
return new UsageModel
var result = new UsageModel();
var properties = result.GetType().GetRuntimeProperties();

foreach (var property in properties)
{
IsGitHubUser = IsGitHubUser,
IsEnterpriseUser = IsEnterpriseUser,
AppVersion = AppVersion,
VSVersion = VSVersion,
Lang = Lang,
NumberOfStartups = NumberOfStartups,
NumberOfStartupsWeek = includeWeekly ? NumberOfStartupsWeek : 0,
NumberOfStartupsMonth = includeMonthly ? NumberOfStartupsMonth : 0,
NumberOfUpstreamPullRequests = NumberOfUpstreamPullRequests,
NumberOfClones = NumberOfClones,
NumberOfReposCreated = NumberOfReposCreated,
NumberOfReposPublished = NumberOfReposPublished,
NumberOfGists = NumberOfGists,
NumberOfOpenInGitHub = NumberOfOpenInGitHub,
NumberOfLinkToGitHub = NumberOfLinkToGitHub,
NumberOfLogins = NumberOfLogins,
NumberOfPullRequestsOpened = NumberOfPullRequestsOpened,
NumberOfLocalPullRequestsCheckedOut = NumberOfLocalPullRequestsCheckedOut,
NumberOfLocalPullRequestPulls = NumberOfLocalPullRequestPulls,
NumberOfLocalPullRequestPushes = NumberOfLocalPullRequestPushes,
NumberOfForkPullRequestsCheckedOut = NumberOfForkPullRequestsCheckedOut,
NumberOfForkPullRequestPulls = NumberOfForkPullRequestPulls,
NumberOfForkPullRequestPushes = NumberOfForkPullRequestPushes,
NumberOfWelcomeDocsClicks = NumberOfWelcomeDocsClicks,
NumberOfWelcomeTrainingClicks = NumberOfWelcomeTrainingClicks,
NumberOfGitHubPaneHelpClicks = NumberOfGitHubPaneHelpClicks,
NumberOfPRDetailsViewChanges = NumberOfPRDetailsViewChanges,
NumberOfPRDetailsViewFile = NumberOfPRDetailsViewFile,
NumberOfPRDetailsCompareWithSolution = NumberOfPRDetailsCompareWithSolution,
NumberOfPRDetailsOpenFileInSolution = NumberOfPRDetailsOpenFileInSolution,
NumberOfPRReviewDiffViewInlineCommentOpen = NumberOfPRReviewDiffViewInlineCommentOpen,
NumberOfPRReviewDiffViewInlineCommentPost = NumberOfPRReviewDiffViewInlineCommentPost,
};
var cloneValue = property.PropertyType == typeof(int);

if (property.Name == nameof(result.NumberOfStartupsWeek))
cloneValue = includeWeekly;
else if (property.Name == nameof(result.NumberOfStartupsMonth))
cloneValue = includeMonthly;

if (cloneValue)
{
var value = property.GetValue(this);
property.SetValue(result, value);
}
}

return result;
}
}
}
53 changes: 53 additions & 0 deletions src/GitHub.Exports/Services/IUsageService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.Threading.Tasks;
using GitHub.Models;

namespace GitHub.Services
{
/// <summary>
/// Provides services for <see cref="IUsageTracker"/>.
/// </summary>
public interface IUsageService
{
/// <summary>
/// Checks whether the last updated date is the same day as today.
/// </summary>
/// <param name="lastUpdated">The last updated date.</param>
/// <returns>True if the last updated date is the same day as today; otherwise false.</returns>
bool IsSameDay(DateTimeOffset lastUpdated);

/// <summary>
/// Checks whether the last updated date is the same week as today.
/// </summary>
/// <param name="lastUpdated">The last updated date.</param>
/// <returns>True if the last updated date is the same week as today; otherwise false.</returns>
bool IsSameWeek(DateTimeOffset lastUpdated);

/// <summary>
/// Checks whether the last updated date is the same month as today.
/// </summary>
/// <param name="lastUpdated">The last updated date.</param>
/// <returns>True if the last updated date is the same month as today; otherwise false.</returns>
bool IsSameMonth(DateTimeOffset lastUpdated);

/// <summary>
/// Starts a timer.
/// </summary>
/// <param name="callback">The callback to call when the timer ticks.</param>
/// <param name="dueTime">The timespan after which the callback will be called the first time.</param>
/// <param name="period">The timespan after which the callback will be called subsequent times.</param>
/// <returns>A disposable used to cancel the timer.</returns>
IDisposable StartTimer(Func<Task> callback, TimeSpan dueTime, TimeSpan period);

/// <summary>
/// Reads the local usage data from disk.
/// </summary>
/// <returns>A task returning a <see cref="UsageData"/> object.</returns>
Task<UsageData> ReadLocalData();

/// <summary>
/// Writes the local usage data to disk.
/// </summary>
Task WriteLocalData(UsageData data);
}
}
26 changes: 4 additions & 22 deletions src/GitHub.Exports/Services/IUsageTracker.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,15 @@
using GitHub.VisualStudio;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System;
using System.Linq.Expressions;
using GitHub.Models;

namespace GitHub.Services
{
[Guid(Guids.UsageTrackerId)]
public interface IUsageTracker
{
Task IncrementLaunchCount();
Task IncrementCloneCount();
Task IncrementCreateCount();
Task IncrementPublishCount();
Task IncrementOpenInGitHubCount();
Task IncrementLinkToGitHubCount();
Task IncrementCreateGistCount();
Task IncrementUpstreamPullRequestCount();
Task IncrementLoginCount();
Task IncrementPullRequestCheckOutCount(bool fork);
Task IncrementPullRequestPullCount(bool fork);
Task IncrementPullRequestPushCount(bool fork);
Task IncrementPullRequestOpened();
Task IncrementWelcomeDocsClicks();
Task IncrementWelcomeTrainingClicks();
Task IncrementGitHubPaneHelpClicks();
Task IncrementPRDetailsViewChanges();
Task IncrementPRDetailsViewFile();
Task IncrementPRDetailsCompareWithSolution();
Task IncrementPRDetailsOpenFileInSolution();
Task IncrementPRReviewDiffViewInlineCommentOpen();
Task IncrementPRReviewDiffViewInlineCommentPost();
Task IncrementCounter(Expression<Func<UsageModel, int>> counter);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ Tuple<ITextSnapshotLine, ITrackingPoint> GetLineAndTrackingPoint(ITextView textV
ExpandCollapsedRegions(textView, line.Extent);
peekBroker.TriggerPeekSession(textView, trackingPoint, InlineCommentPeekRelationship.Instance.Name);

usageTracker.IncrementPRReviewDiffViewInlineCommentOpen().Forget();
usageTracker.IncrementCounter(x => x.NumberOfPRReviewDiffViewInlineCommentOpen).Forget();

return Tuple.Create(line, trackingPoint);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ public async Task<IPullRequestReviewCommentModel> PostReviewComment(
path,
position);

await usageTracker.IncrementPRReviewDiffViewInlineCommentPost();
await usageTracker.IncrementCounter(x => x.NumberOfPRReviewDiffViewInlineCommentPost);

return new PullRequestReviewCommentModel
{
Expand Down Expand Up @@ -329,7 +329,7 @@ public async Task<IPullRequestReviewCommentModel> PostReviewComment(
body,
inReplyTo);

await usageTracker.IncrementPRReviewDiffViewInlineCommentPost();
await usageTracker.IncrementCounter(x => x.NumberOfPRReviewDiffViewInlineCommentPost);

return new PullRequestReviewCommentModel
{
Expand Down
4 changes: 2 additions & 2 deletions src/GitHub.TeamFoundation.14/Home/GitHubHomeSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,11 @@ void ShowWelcomeMessage()
{
case "show-training":
visualStudioBrowser.OpenUrl(new Uri(TrainingUrl));
usageTracker.IncrementWelcomeTrainingClicks().Forget();
usageTracker.IncrementCounter(x => x.NumberOfWelcomeTrainingClicks).Forget();
break;
case "show-docs":
visualStudioBrowser.OpenUrl(new Uri(GitHubUrls.Documentation));
usageTracker.IncrementWelcomeDocsClicks().Forget();
usageTracker.IncrementCounter(x => x.NumberOfWelcomeDocsClicks).Forget();
break;
case "dont-show-again":
teamExplorerServices.HideNotification(welcomeMessageGuid);
Expand Down
1 change: 1 addition & 0 deletions src/GitHub.VisualStudio/GitHub.VisualStudio.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@
<Compile Include="Helpers\Browser.cs" />
<Compile Include="Services\JsonConnectionCache.cs" />
<Compile Include="Services\UIProvider.cs" />
<Compile Include="Services\UsageService.cs" />
<Compile Include="Services\UsageTracker.cs" />
<Compile Include="Services\LoginManagerDispatcher.cs" />
<Compile Include="Services\UsageTrackerDispatcher.cs" />
Expand Down
6 changes: 4 additions & 2 deletions src/GitHub.VisualStudio/GitHubPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,10 @@ async Task<object> CreateService(IAsyncServiceContainer container, CancellationT
}
else if (serviceType == typeof(IUsageTracker))
{
var uiProvider = await GetServiceAsync(typeof(IGitHubServiceProvider)) as IGitHubServiceProvider;
return new UsageTracker(uiProvider);
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var serviceProvider = await GetServiceAsync(typeof(IGitHubServiceProvider)) as IGitHubServiceProvider;
var usageService = serviceProvider.GetService<IUsageService>();
return new UsageTracker(serviceProvider, usageService);
}
else if (serviceType == typeof(IUIProvider))
{
Expand Down
2 changes: 1 addition & 1 deletion src/GitHub.VisualStudio/Menus/BlameLink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public async void Activate(object data = null)
var browser = ServiceProvider.TryGetService<IVisualStudioBrowser>();
browser?.OpenUrl(link.ToUri());

await UsageTracker.IncrementOpenInGitHubCount();
await UsageTracker.IncrementCounter(x => x.NumberOfOpenInGitHub);
}
}
}
2 changes: 1 addition & 1 deletion src/GitHub.VisualStudio/Menus/CopyLink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public async void Activate(object data = null)
Clipboard.SetText(link);
var ns = ServiceProvider.TryGetService<IStatusBarNotificationService>();
ns?.ShowMessage(Resources.LinkCopiedToClipboardMessage);
await UsageTracker.IncrementLinkToGitHubCount();
await UsageTracker.IncrementCounter(x => x.NumberOfLinkToGitHub);
}
catch
{
Expand Down
2 changes: 1 addition & 1 deletion src/GitHub.VisualStudio/Menus/OpenLink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public async void Activate(object data = null)
var browser = ServiceProvider.TryGetService<IVisualStudioBrowser>();
browser?.OpenUrl(link.ToUri());

await UsageTracker.IncrementOpenInGitHubCount();
await UsageTracker.IncrementCounter(x => x.NumberOfOpenInGitHub);
}
}
}
Loading