From 4f19dc2615b40ff3cca2d8f096484934a8ae2f11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20H=C3=B6rnfeldt?= Date: Mon, 31 Jan 2022 15:04:39 +0100 Subject: [PATCH 1/5] Update packages Migrated package.config to PackageReference. Remove application signature to be able to use the IniWrapper package. Some packages is no longer needed as Microsoft.VisualStudio.SDK contaions most assets. --- ActivityWatch.API/ActivityWatch.API.csproj | 17 +- ActivityWatch.API/Key.snk | Bin 596 -> 0 bytes ActivityWatch.API/packages.config | 4 - ActivityWatchVS/ActivityWatchVS.csproj | 193 ++------------------- ActivityWatchVS/Binaries/IniWrapper.dll | Bin 35840 -> 0 bytes ActivityWatchVS/app.config | 2 +- ActivityWatchVS/packages.config | 29 ---- 7 files changed, 24 insertions(+), 221 deletions(-) delete mode 100644 ActivityWatch.API/Key.snk delete mode 100644 ActivityWatch.API/packages.config delete mode 100644 ActivityWatchVS/Binaries/IniWrapper.dll delete mode 100644 ActivityWatchVS/packages.config diff --git a/ActivityWatch.API/ActivityWatch.API.csproj b/ActivityWatch.API/ActivityWatch.API.csproj index fc625a7..70272f0 100644 --- a/ActivityWatch.API/ActivityWatch.API.csproj +++ b/ActivityWatch.API/ActivityWatch.API.csproj @@ -12,7 +12,6 @@ v4.7.2 512 true - true @@ -33,18 +32,16 @@ 4 - true + false - Key.snk + + false - - ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll - @@ -65,10 +62,12 @@ - - - + + + 13.0.1 + + \ No newline at end of file diff --git a/ActivityWatch.API/Key.snk b/ActivityWatch.API/Key.snk deleted file mode 100644 index 4e3762411fa52c8084b3cc64d91448ef033c37a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa500971jD55(LHZ z>X_#V35PH1f5z*zIE-*K1TA|pc=e^Gb@=ZK86E8O#d6>MsQnhQG-QmhMwE4pj%j@C zs20=KjBbVtdJ)|zJbUU%5Zq^m`xD8^S_pSvJU1k3Ewg+LNWp2edzFPOq-rJeQjhIJ z*#8UVhPha(L6U9Kz+9DX1J0qd%C3vgfZpL50&NAMU$$d;Q4j$R8VxGEE0XL>(yaFX-wRjfnT{ZpzVY9HH>m3k zmq4m5+Vwdw`dr(*R%{3cfYq$t;!@nn-0d zYg724BYvJ8thkmY(R8^wI`X2~M|b7ozSC~osvxux!Q*RGRHr>&$Ix0@cgd+fv@RFF zoougv4g3?88&(Q!LQ+D+PZ**)kBfP0 - - - \ No newline at end of file diff --git a/ActivityWatchVS/ActivityWatchVS.csproj b/ActivityWatchVS/ActivityWatchVS.csproj index 1d28b99..81a229f 100644 --- a/ActivityWatchVS/ActivityWatchVS.csproj +++ b/ActivityWatchVS/ActivityWatchVS.csproj @@ -1,19 +1,12 @@  - 15.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - true - - true - - - Key.snk + false AWPackage.ico @@ -98,9 +91,6 @@ GeneralSettings.Designer.cs - - Designer - Designer @@ -112,7 +102,6 @@ Menus.ctmenu - Always @@ -130,160 +119,32 @@ - - False - - - False - - - False - - - False - - - False - Binaries\IniWrapper.dll - - - ..\packages\Microsoft.ApplicationInsights.2.0.1\lib\net46\Microsoft.ApplicationInsights.dll - True - - - - False - ..\..\..\..\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Microsoft.TeamFoundation.Client.dll - - - False - ..\..\..\..\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Microsoft.TeamFoundation.Controls.dll - - - False - ..\..\..\..\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Microsoft.TeamFoundation.VersionControl.Client.dll - - - False - ..\..\..\..\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Microsoft.TeamFoundation.VersionControl.Common.dll - - - False - ..\..\..\..\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Microsoft.TeamFoundation.VersionControl.Controls.Common.dll - - - False - - - ..\packages\Microsoft.VisualStudio.CoreUtility.15.0.26228\lib\net45\Microsoft.VisualStudio.CoreUtility.dll - True - - - ..\packages\Microsoft.VisualStudio.Imaging.15.0.26228\lib\net45\Microsoft.VisualStudio.Imaging.dll - True - - - ..\packages\Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.14.3.25408\lib\net20\Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll - True - - - ..\packages\Microsoft.VisualStudio.OLE.Interop.7.10.6071\lib\Microsoft.VisualStudio.OLE.Interop.dll - - - ..\packages\Microsoft.VisualStudio.Shell.15.0.15.0.26228\lib\Microsoft.VisualStudio.Shell.15.0.dll - True - - - ..\packages\Microsoft.VisualStudio.Shell.Framework.15.0.26228\lib\net45\Microsoft.VisualStudio.Shell.Framework.dll - True - - - ..\packages\Microsoft.VisualStudio.Shell.Interop.7.10.6071\lib\Microsoft.VisualStudio.Shell.Interop.dll - True - - - ..\packages\Microsoft.VisualStudio.Shell.Interop.10.0.10.0.30319\lib\Microsoft.VisualStudio.Shell.Interop.10.0.dll - True - - - ..\packages\Microsoft.VisualStudio.Shell.Interop.11.0.11.0.61030\lib\Microsoft.VisualStudio.Shell.Interop.11.0.dll - True - - - ..\packages\Microsoft.VisualStudio.Shell.Interop.12.0.12.0.30110\lib\Microsoft.VisualStudio.Shell.Interop.12.0.dll - True - - - ..\packages\Microsoft.VisualStudio.Shell.Interop.14.0.DesignTime.14.3.25407\lib\Microsoft.VisualStudio.Shell.Interop.14.0.DesignTime.dll - True - - - ..\packages\Microsoft.VisualStudio.Shell.Interop.8.0.8.0.50727\lib\Microsoft.VisualStudio.Shell.Interop.8.0.dll - True - - - ..\packages\Microsoft.VisualStudio.Shell.Interop.9.0.9.0.30729\lib\Microsoft.VisualStudio.Shell.Interop.9.0.dll - True - - - False - ..\..\..\..\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Microsoft.VisualStudio.TeamFoundation.dll - - - ..\..\..\..\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Microsoft.VisualStudio.TeamFoundation.VersionControl.dll - - - ..\packages\Microsoft.VisualStudio.TextManager.Interop.7.10.6070\lib\Microsoft.VisualStudio.TextManager.Interop.dll - True - - - ..\packages\Microsoft.VisualStudio.TextManager.Interop.8.0.8.0.50727\lib\Microsoft.VisualStudio.TextManager.Interop.8.0.dll - True - - - ..\packages\Microsoft.VisualStudio.Threading.15.0.240\lib\net45\Microsoft.VisualStudio.Threading.dll - True - - - ..\packages\Microsoft.VisualStudio.Utilities.15.0.26228\lib\net46\Microsoft.VisualStudio.Utilities.dll - True - - - ..\packages\Microsoft.VisualStudio.Validation.15.0.82\lib\net45\Microsoft.VisualStudio.Validation.dll - True - + + 4.1.0 + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + - - False - - - ..\packages\System.IO.Abstractions.2.1.0.178\lib\net40\System.IO.Abstractions.dll - True - - - ..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll - True - True - - - ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll - - - - - - PublicResXFileCodeGenerator @@ -306,30 +167,6 @@ MSBuild:Compile - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - \ No newline at end of file diff --git a/ActivityWatchVS/Binaries/IniWrapper.dll b/ActivityWatchVS/Binaries/IniWrapper.dll deleted file mode 100644 index c00bdad97f028fa4ff5ecbba05bf0eb08274f06b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35840 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 Ve~TyXF1Y_at^WU3{)brLe*uJO)_VW| diff --git a/ActivityWatchVS/app.config b/ActivityWatchVS/app.config index 03d1ab3..92819f4 100644 --- a/ActivityWatchVS/app.config +++ b/ActivityWatchVS/app.config @@ -9,7 +9,7 @@ - + diff --git a/ActivityWatchVS/packages.config b/ActivityWatchVS/packages.config deleted file mode 100644 index 49dfeed..0000000 --- a/ActivityWatchVS/packages.config +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 074a0dd21418253d66d2df236d03722133203cbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20H=C3=B6rnfeldt?= Date: Tue, 1 Feb 2022 15:53:26 +0100 Subject: [PATCH 2/5] Add log messages to queue and flush on idle Fix issue logging from non UI threads. --- .../Listeners/DTE2EventListener.cs | 7 +++ ActivityWatchVS/Services/LogService.cs | 46 +++++++++++++------ 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/ActivityWatchVS/Listeners/DTE2EventListener.cs b/ActivityWatchVS/Listeners/DTE2EventListener.cs index 5334158..4973d64 100644 --- a/ActivityWatchVS/Listeners/DTE2EventListener.cs +++ b/ActivityWatchVS/Listeners/DTE2EventListener.cs @@ -1,4 +1,7 @@ using EnvDTE; + +using Microsoft.VisualStudio.Shell; + using System; using System.IO; using System.Runtime.CompilerServices; @@ -22,6 +25,8 @@ internal sealed class DTE2EventListener : IDisposable public DTE2EventListener(AWPackage package) { + ThreadHelper.ThrowIfNotOnUIThread(); + this._package = package; var dte2Events = this._package.DTE2Service.Events; @@ -183,6 +188,8 @@ private void solutionEvents_Opened() public void Dispose() { + ThreadHelper.ThrowIfNotOnUIThread(); + _buildEv.OnBuildBegin -= buildEvents_OnBuildBegin; _buildEv.OnBuildDone -= buildEvents_OnBuildDone; _documentEv.DocumentOpened -= documentEv_DocumentOpened; diff --git a/ActivityWatchVS/Services/LogService.cs b/ActivityWatchVS/Services/LogService.cs index a28b57b..b88f507 100644 --- a/ActivityWatchVS/Services/LogService.cs +++ b/ActivityWatchVS/Services/LogService.cs @@ -1,5 +1,7 @@ -using Microsoft.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; using System; +using System.Collections.Concurrent; using System.Diagnostics; using System.Reflection; @@ -9,8 +11,10 @@ internal class LogService { #region Fields - private AWPackage _package; - private IVsOutputWindowPane _vsOutputWindowPane; + private readonly AWPackage _package; + private readonly IVsOutputWindowPane _vsOutputWindowPane; + private readonly ConcurrentQueue _logQueue; + private volatile bool _activate; #endregion Fields @@ -18,17 +22,19 @@ internal class LogService public LogService(AWPackage package, IVsOutputWindowPane vsOutputWindowPane) { + ThreadHelper.ThrowIfNotOnUIThread(); + + _logQueue = new ConcurrentQueue(); _package = package; _vsOutputWindowPane = vsOutputWindowPane; _vsOutputWindowPane.SetName(AWPackage.NAME_CS_PLUGIN); - bool activate = false; #if DEBUG LogLevel = EErrorLevel.Debug; - activate = true; + _activate = true; #endif // say hello - Log(AWPackage.NAME_CS_PLUGIN + " " + getCurrentVersion() + " running", EErrorLevel.Info, activate); + Log(AWPackage.NAME_CS_PLUGIN + " " + getCurrentVersion() + " running", EErrorLevel.Info); } #endregion Constructors @@ -61,16 +67,28 @@ internal void Log(string msg, EErrorLevel errorLevel = EErrorLevel.Debug, bool a { return; } - try + + _logQueue.Enqueue(msg + "\r\n"); + + _activate = _activate || activate; + + _ = _package.JoinableTaskFactory.StartOnIdle(FlushLogsToOutputWindowPane, VsTaskRunContext.UIThreadBackgroundPriority); + } + + private void FlushLogsToOutputWindowPane() + { + ThreadHelper.ThrowIfNotOnUIThread(); + + if(_activate) { - _vsOutputWindowPane.OutputString(msg + "\r\n"); - if (activate) - { - _vsOutputWindowPane.Activate(); - } + _vsOutputWindowPane.Activate(); + _activate = false; + } + + while (_logQueue.Count > 0 && _logQueue.TryDequeue(out string msg)) + { + _vsOutputWindowPane.OutputStringThreadSafe(msg); } - catch - { } } private string getCurrentVersion() From a21dae246e259193eaa0aeb8ec78e2b9eec57cd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20H=C3=B6rnfeldt?= Date: Tue, 1 Feb 2022 16:06:01 +0100 Subject: [PATCH 3/5] Make use of JoinableTaskFactory to handle async tasks --- ActivityWatchVS/AWPackage.cs | 35 +-- ActivityWatchVS/Services/AWOptionService.cs | 2 +- ActivityWatchVS/Services/EventService.cs | 226 +++++++++++--------- 3 files changed, 140 insertions(+), 123 deletions(-) diff --git a/ActivityWatchVS/AWPackage.cs b/ActivityWatchVS/AWPackage.cs index 275cda8..9543520 100644 --- a/ActivityWatchVS/AWPackage.cs +++ b/ActivityWatchVS/AWPackage.cs @@ -82,52 +82,55 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke { _progress = progress; _progress.Report(new ServiceProgressData("ActivityWatchVS starting")); - this.DisposalToken.Register(() => shutdown()); + this.DisposalToken.Register(() => this.Dispose()); // background thread - await BackgroundThreadInitialization(); + await JoinableTaskFactory.StartOnIdle(() => BackgroundThreadInitializationAsync(), VsTaskRunContext.UIThreadBackgroundPriority); + // main thread - await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - await MainThreadInitialization(); + await MainThreadInitializationAsync(); _isReady = true; _progress.Report(new ServiceProgressData("ActivityWatchVS running")); } - private async Task BackgroundThreadInitialization() + private async Task BackgroundThreadInitializationAsync() { - // Logger - _logService = new Services.LogService(this, await GetServiceAsync(typeof(SVsGeneralOutputWindowPane)) as IVsOutputWindowPane); - try { // ... Services VS _dte2Service = await GetServiceAsync(typeof(DTE)) as DTE2; // ... our Services - _awBinaryService = new Services.AwBinaryService(this); - _eventService = new Services.EventService(this); + _awBinaryService = new AwBinaryService(this); + _eventService = new EventService(this); // we are ready to send events // ... Listeners - _dte2EventListener = new Listeners.DTE2EventListener(this); + _dte2EventListener = new DTE2EventListener(this); } catch (Exception ex) { - _logService.Log(ex, "ActivityWatchVS: This is a bug, please report it!", activate: true); + _logService?.Log(ex, "ActivityWatchVS: This is a bug, please report it!"); } } - private async Task MainThreadInitialization() + private async Task MainThreadInitializationAsync() { - try { + await JoinableTaskFactory.SwitchToMainThreadAsync(DisposalToken); + + // Logger + _logService = new LogService(this, await GetServiceAsync(typeof(SVsGeneralOutputWindowPane)) as IVsOutputWindowPane); + + try + { // single class for AW ini file and our own settings - _awOptions = await Services.AWOptionService.InitializeAsync(this); + _awOptions = Services.AWOptionService.Initialize(this); } catch (Exception ex) { - _logService.Log(ex, "ActivityWatchVS: This is a bug, please report it!", activate: true); + _logService.Log(ex, "ActivityWatchVS: This is a bug, please report it!"); } } diff --git a/ActivityWatchVS/Services/AWOptionService.cs b/ActivityWatchVS/Services/AWOptionService.cs index 0a912c5..782a6ed 100644 --- a/ActivityWatchVS/Services/AWOptionService.cs +++ b/ActivityWatchVS/Services/AWOptionService.cs @@ -70,7 +70,7 @@ public bool IsProductive #region Methods - internal static async Task InitializeAsync(AWPackage package) + internal static AWOptionService Initialize(AWPackage package) { return new AWOptionService(package); } diff --git a/ActivityWatchVS/Services/EventService.cs b/ActivityWatchVS/Services/EventService.cs index 848151c..5313bc5 100644 --- a/ActivityWatchVS/Services/EventService.cs +++ b/ActivityWatchVS/Services/EventService.cs @@ -1,5 +1,9 @@ using ActivityWatch.API.V1; using ActivityWatchVS.Tools; + +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Threading; + using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -16,22 +20,21 @@ internal class EventService private const double AFK_SECONDS = 60 * 15; private const double MIN_HEARTBEAT_SECONDS = 60; - private const int THREAD_WAIT_TIMEOUT_SECONDS = 60; private const int WAIT_FOR_EVENT_SECONDS = 20; #endregion Constants #region Fields - private CancellationTokenSource _cancellationTokenSource; private Client _client; - private ManualResetEvent _continueLoopManualResetEvent = new ManualResetEvent(false); - private bool _doShutdown = false; - private ConcurrentQueue _events = new ConcurrentQueue(); private bool _isBucketSent = false; - private AWPackage _package; - private Task _thread = null; - private Dictionary bucketIdPartLastEvent = new Dictionary(); + private Task _currentTask = Task.CompletedTask; + + private readonly object _currentTaskLock = new object(); + private readonly AWPackage _package; + private readonly ConcurrentQueue _events = new ConcurrentQueue(); + private readonly Dictionary _bucketIdPartLastEvent = new Dictionary(); + private readonly Semaphore _semaphore = new Semaphore(1, 1, typeof(EventService).FullName); #endregion Fields @@ -42,10 +45,6 @@ internal EventService(AWPackage package) _package = package; } - private EventService() - { - } - #endregion Constructors #region Methods @@ -55,48 +54,46 @@ public void Reset() _isBucketSent = false; } - internal void AddEvent(ActivityWatch.API.V1.Event ev) + internal void AddEvent(Event ev) { - if (_doShutdown) //(_cancellationTokenSource?.IsCancellationRequested ?? false) - { + if (_package.DisposalToken.IsCancellationRequested) return; - } + _events.Enqueue(ev); - _continueLoopManualResetEvent.Set(); - startThread(); + + lock(_currentTaskLock) + { + if (_currentTask.IsCompleted) + { + _currentTask = this.ScheduleBackgroundTaskAsync(() => this.ProcessEventQueueAsync(_package.DisposalToken)); + } + } } internal void Shutdown() { - //_cancellationTokenSource?.Cancel(); - _doShutdown = true; - _continueLoopManualResetEvent.Set(); - - //if (_thread != null) - //{ - // Task.WaitAll(new Task[] { _thread }, THREAD_WAIT_TIMEOUT_SECONDS * 1000); - //} - _thread?.Wait(THREAD_WAIT_TIMEOUT_SECONDS * 1000); + _package.JoinableTaskFactory.Run(ProcessEventsAsync); } - private static string getBucketId(Event ev) + private static string GetBucketId(Event ev) { return $"{ev.Data.BucketIDCustomPart}_{Environment.MachineName}"; } - private bool mergeEventsAndOutFinishedEvent(out ActivityWatch.API.V1.Event logEvent) + private bool MergeEventsAndOutFinishedEvent(out Event logEvent) { logEvent = null; - if (_events.TryDequeue(out ActivityWatch.API.V1.Event newEvent)) + if (_events.TryDequeue(out Event newEvent)) { - _package.LogService.Log($"new Event for {getBucketId(newEvent)}: " + newEvent.ToJson(), LogService.EErrorLevel.Debug); + _package.LogService.Log($"new Event for {GetBucketId(newEvent)}: " + newEvent.ToJson(), LogService.EErrorLevel.Debug); + + Event oldEvent = null; - ActivityWatch.API.V1.Event oldEvent = null; // do we have an old event? - if (bucketIdPartLastEvent.ContainsKey(newEvent.Data.BucketIDCustomPart)) + if (_bucketIdPartLastEvent.ContainsKey(newEvent.Data.BucketIDCustomPart)) { // compare old to new event - oldEvent = bucketIdPartLastEvent[newEvent.Data.BucketIDCustomPart]; + oldEvent = _bucketIdPartLastEvent[newEvent.Data.BucketIDCustomPart]; var duration = (newEvent.Timestamp - oldEvent.Timestamp).TotalSeconds; oldEvent.Duration = duration; @@ -107,8 +104,8 @@ private bool mergeEventsAndOutFinishedEvent(out ActivityWatch.API.V1.Event logEv else if (!oldEvent.Equals(newEvent)) { // different event, log and keep the new one - bucketIdPartLastEvent.Remove(oldEvent.Data.BucketIDCustomPart); - bucketIdPartLastEvent[newEvent.Data.BucketIDCustomPart] = newEvent; + _bucketIdPartLastEvent.Remove(oldEvent.Data.BucketIDCustomPart); + _bucketIdPartLastEvent[newEvent.Data.BucketIDCustomPart] = newEvent; logEvent = oldEvent; return true; } @@ -116,25 +113,25 @@ private bool mergeEventsAndOutFinishedEvent(out ActivityWatch.API.V1.Event logEv { // same event, but older than minimum hearbeat interval different event, push // old event with new duration, and save old - bucketIdPartLastEvent[newEvent.Data.BucketIDCustomPart] = newEvent; + _bucketIdPartLastEvent[newEvent.Data.BucketIDCustomPart] = newEvent; } } else { // no old event, keep the record - bucketIdPartLastEvent[newEvent.Data.BucketIDCustomPart] = newEvent; + _bucketIdPartLastEvent[newEvent.Data.BucketIDCustomPart] = newEvent; } } else { - if (_doShutdown) //(_cancellationTokenSource.IsCancellationRequested) + if (_package.DisposalToken.IsCancellationRequested) { // we are shutting down, create stop events - var stopEvent = bucketIdPartLastEvent.Values.FirstOrDefault(); + var stopEvent = _bucketIdPartLastEvent.Values.FirstOrDefault(); if (stopEvent != null) { // write event, we are about to stop - bucketIdPartLastEvent.Remove(stopEvent.Data.BucketIDCustomPart); + _bucketIdPartLastEvent.Remove(stopEvent.Data.BucketIDCustomPart); stopEvent.Duration = (DateTimeOffset.UtcNow - stopEvent.Timestamp).TotalSeconds; logEvent = stopEvent; return true; @@ -143,11 +140,11 @@ private bool mergeEventsAndOutFinishedEvent(out ActivityWatch.API.V1.Event logEv else { // nothing to dequeue, create stop events (AFK) - var stopEvent = bucketIdPartLastEvent.Values.FirstOrDefault(e => e.Timestamp.AddSeconds((int)e.Duration) < DateTimeOffset.UtcNow.AddSeconds(-AFK_SECONDS)); + var stopEvent = _bucketIdPartLastEvent.Values.FirstOrDefault(e => e.Timestamp.AddSeconds((int)e.Duration) < DateTimeOffset.UtcNow.AddSeconds(-AFK_SECONDS)); if (stopEvent != null) { // write event, user is afk - bucketIdPartLastEvent.Remove(stopEvent.Data.BucketIDCustomPart); + _bucketIdPartLastEvent.Remove(stopEvent.Data.BucketIDCustomPart); stopEvent.Duration = AFK_SECONDS; logEvent = stopEvent; return true; @@ -157,23 +154,25 @@ private bool mergeEventsAndOutFinishedEvent(out ActivityWatch.API.V1.Event logEv return false; } - private async Task postBucketIfNeededAsync(string bucket_id, string bucketType, CancellationToken cancellationToken) + private async Task PostCreateBucketAsync(string bucket_id, string bucketType, CancellationToken cancellationToken) { if (!_isBucketSent || _package.AwOptions.ActivityWatchBaseURL != _client?.BaseUrl) { - _client = new ActivityWatch.API.V1.Client(); + _client = new Client(); _client.BaseUrl = _package.AwOptions.ActivityWatchBaseURL; - var awBucket = new ActivityWatch.API.V1.CreateBucket() + + var awBucket = new CreateBucket() { Client = AWPackage.NAME_ACTIVITY_WATCHER, Hostname = Environment.MachineName, Type = bucketType }; + try { var bucketResult = await _client.BucketsPostAsync(awBucket, bucket_id, cancellationToken).ConfigureAwait(false); } - catch (ActivityWatch.API.V1.AWApiException ex) + catch (AWApiException ex) { if (ex.StatusCode == 304) { @@ -184,85 +183,100 @@ private async Task postBucketIfNeededAsync(string bucket_id, string bucketType, throw; } } - _isBucketSent = true; + + return true; } + + return false; } - private void pushEventsThread(CancellationToken cancellationToken) + private async Task PushEventAsync(Event logEvent, CancellationToken cancellationToken) { - for (; ; ) + cancellationToken.ThrowIfCancellationRequested(); + + await TaskScheduler.Default; + + try { - try + var bucket_id = GetBucketId(logEvent); + + bool ok = false; + do { - bool hasFired = _continueLoopManualResetEvent.WaitOne(WAIT_FOR_EVENT_SECONDS * 1000); - while (mergeEventsAndOutFinishedEvent(out ActivityWatch.API.V1.Event logEvent)) + try { - var bucket_id = getBucketId(logEvent); + if (!_isBucketSent) + { + _isBucketSent = await PostCreateBucketAsync(bucket_id, logEvent.Data.TypeName, cancellationToken); + } - bool ok = false; - do + await _client.BucketsIdEventsPostAsync(logEvent, bucket_id, cancellationToken); + + _package.LogService.Log($"Sent event for {bucket_id}: " + logEvent.ToJson(), LogService.EErrorLevel.Debug); + ok = true; + } + catch (Exception ex) + { + var sockEx = ex.GetInnerst(); + if (sockEx != null) { - try - { - //await - postBucketIfNeededAsync(bucket_id, logEvent.Data.TypeName, _cancellationTokenSource.Token) - .GetAwaiter().GetResult(); - //await - _client.BucketsIdEventsPostAsync(logEvent, bucket_id, _cancellationTokenSource.Token) - .GetAwaiter().GetResult(); - _package.LogService.Log($"Sent event for {bucket_id}: " + logEvent.ToJson(), LogService.EErrorLevel.Debug); - ok = true; - } - catch (Exception ex) + if (sockEx.SocketErrorCode == SocketError.ConnectionRefused) { - var sockEx = ex.GetInnerst(); - if (sockEx != null) - { - if(sockEx.SocketErrorCode == SocketError.ConnectionRefused) - { - //aw_service is not running, try to find and start it - _package.AwBinaryService.TryStartAwServer(); - } - } - - // some error, retry regularly - _package.LogService.Log(ex, logEvent.ToJson()); - if (!_doShutdown) //(!cancellationToken.IsCancellationRequested) - { - Reset(); - // don't ddos - Thread.Sleep(5000); - } + //aw_service is not running, try to find and start it + _package.AwBinaryService.TryStartAwServer(); } - } while (!ok && !_doShutdown); //cancellationToken.IsCancellationRequested); // don't retry if we do shut down - } - _continueLoopManualResetEvent.Reset(); - if (_doShutdown && _events.IsEmpty) //_events.IsEmpty needed? - { - break; + } + + // some error, retry regularly + _package.LogService.Log(ex, logEvent.ToJson()); + Reset(); + // don't ddos + await Task.Delay(5000); } - } - catch (Exception ex) - { - _package.LogService.Log(ex); - } + } while (!ok); + } + catch (Exception ex) + { + _package.LogService.Log(ex); + } + } + + private async Task ScheduleBackgroundTaskAsync(Func action) + { + try + { + await _package.JoinableTaskFactory.StartOnIdle(action); + } + catch (Exception ex) + { + _package.LogService.Log(ex); } - _package.LogService.Log("EventService loop ended", LogService.EErrorLevel.Debug); } - private void startThread() + private Task ProcessEventsAsync() => ProcessEventQueueAsync(CancellationToken.None); + + private async Task ProcessEventQueueAsync(CancellationToken token) { - if (_thread == null) + await TaskScheduler.Default; + + if (!_semaphore.WaitOne(WAIT_FOR_EVENT_SECONDS * 1000)) + { + return; + } + + try { - lock (this) + while (MergeEventsAndOutFinishedEvent(out Event logEvent)) { - if (_thread == null) - { - _cancellationTokenSource = new CancellationTokenSource(); - _thread = Task.Run(() => pushEventsThread(_cancellationTokenSource.Token)); - } + await PushEventAsync(logEvent, token); } } + finally + { + _semaphore.Release(); + } + + _package.LogService.Log("EventService loop ended", LogService.EErrorLevel.Debug); } #endregion Methods From 3ae983dec4a9f9f26004fc436e6d3e4811d1e272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20H=C3=B6rnfeldt?= Date: Tue, 1 Feb 2022 16:07:50 +0100 Subject: [PATCH 4/5] Add target for VS2022 --- ActivityWatchVS/source.extension.vsixmanifest | 67 ++++++++++++------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/ActivityWatchVS/source.extension.vsixmanifest b/ActivityWatchVS/source.extension.vsixmanifest index 2c72e98..0602fad 100644 --- a/ActivityWatchVS/source.extension.vsixmanifest +++ b/ActivityWatchVS/source.extension.vsixmanifest @@ -1,32 +1,47 @@  - - - ActivityWatchVS - Track your work with this plugin and activitywatch.net. Ever wanted to know where you spend your time? + + + ActivityWatchVS + Track your work with this plugin and activitywatch.net. Ever wanted to know where you spend your time? The Plugin is a Watcher for Visual Studio. It enables tracking of all, you do in your solution. We send this data to an Activity Watch installation on your machine, all tracked data belongs to you. Activity Watch tracks windows titles, we extend this functionality from inside Visual Studio and track your file edits. - https://github.com/LaggAt/ActivityWatchVS/ - LICENSE.txt - GETTING_STARTED.txt - CHANGELOG.md - Resources\AWPackage.ico - Resources\Screenshots\VS-Options-Dialog.png - Activity Watch, quantified self, lifelog, coding, tracking - - - - - - - - - - - - - - - + https://github.com/LaggAt/ActivityWatchVS/ + LICENSE.txt + GETTING_STARTED.txt + CHANGELOG.md + Resources\AWPackage.ico + Resources\Screenshots\VS-Options-Dialog.png + Activity Watch, quantified self, lifelog, coding, tracking + + + + x86 + + + x86 + + + x86 + + + amd64 + + + amd64 + + + amd64 + + + + + + + + + + + \ No newline at end of file From 5ce45a394a49ab9aa2d4062d095cf3b1ac9d6ae7 Mon Sep 17 00:00:00 2001 From: Florian Lagg Date: Wed, 17 Aug 2022 06:51:44 +0200 Subject: [PATCH 5/5] push AppVeyour image to VS2022 add changelog push testing version to 1.9 (stable VS2022 Support should be 2.0) --- ActivityWatch.API/Properties/AssemblyInfo.cs | 4 ++-- ActivityWatchVS/CHANGELOG.md | 4 ++++ ActivityWatchVS/Properties/AssemblyInfo.cs | 4 ++-- ActivityWatchVS/source.extension.cs | 2 +- appveyor.yml | 4 ++-- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/ActivityWatch.API/Properties/AssemblyInfo.cs b/ActivityWatch.API/Properties/AssemblyInfo.cs index a5f7502..cfb185a 100644 --- a/ActivityWatch.API/Properties/AssemblyInfo.cs +++ b/ActivityWatch.API/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.1.0.0")] -[assembly: AssemblyFileVersion("1.1.0.0")] +[assembly: AssemblyVersion("1.9.0")] +[assembly: AssemblyFileVersion("1.9.0")] \ No newline at end of file diff --git a/ActivityWatchVS/CHANGELOG.md b/ActivityWatchVS/CHANGELOG.md index f4acd09..fa84b51 100644 --- a/ActivityWatchVS/CHANGELOG.md +++ b/ActivityWatchVS/CHANGELOG.md @@ -17,6 +17,10 @@ or on vsixgallery.com (beta/alpha/testing) - [ ] TFS / Work Item tracking - [ ] ... your ideas +## 1.9.0 (testing) Visual Studio 2022 support + +- [x] thanks to https://github.com/DarkOoze we have VS2022 Support in testing now. + ## 1.1.x (stable) get versioning right - [x] fix appveyor/vsixmanifest files for correct version numbers everywhere https://github.com/LaggAt/ActivityWatchVS/issues/2 diff --git a/ActivityWatchVS/Properties/AssemblyInfo.cs b/ActivityWatchVS/Properties/AssemblyInfo.cs index 1e11a52..6027cdd 100644 --- a/ActivityWatchVS/Properties/AssemblyInfo.cs +++ b/ActivityWatchVS/Properties/AssemblyInfo.cs @@ -22,5 +22,5 @@ // // You can specify all the values or you can default the Build and Revision Numbers by using the '*' // as shown below: [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.1.*")] -[assembly: AssemblyFileVersion("1.1.*")] \ No newline at end of file +[assembly: AssemblyVersion("1.9.0")] +[assembly: AssemblyFileVersion("1.9.0")] \ No newline at end of file diff --git a/ActivityWatchVS/source.extension.cs b/ActivityWatchVS/source.extension.cs index 0505b9c..69bfbf3 100644 --- a/ActivityWatchVS/source.extension.cs +++ b/ActivityWatchVS/source.extension.cs @@ -14,7 +14,7 @@ internal sealed partial class Vsix Activity Watch tracks windows titles, we extend this functionality from inside Visual Studio and track your file edits."; public const string Language = "en-US"; - public const string Version = "1.1.0"; + public const string Version = "1.9.0"; public const string Author = "Florian Lagg"; public const string Tags = "Activity Watch, quantified self, lifelog, coding, tracking"; } diff --git a/appveyor.yml b/appveyor.yml index a8d840a..3cba25b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -image: Visual Studio 2017 +image: Visual Studio 2022 branches: only: - stable @@ -6,7 +6,7 @@ branches: - alpha - testing -version: 1.1.{build} +version: 1.9.{build} install: - ps: (new-object Net.WebClient).DownloadString("https://raw.github.com/madskristensen/ExtensionScripts/master/AppVeyor/vsix.ps1") | iex