Skip to content

Commit

Permalink
perf: ⚡ use semaphore to protect summary/detailed report fetch (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesNZL committed Jul 3, 2023
1 parent 9c88afa commit 87a894d
Showing 1 changed file with 43 additions and 5 deletions.
48 changes: 43 additions & 5 deletions src/TogglTrack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ internal class TogglTrack
SemaphoreSlim Token,
SemaphoreSlim Me,
SemaphoreSlim RunningTimeEntries,
SemaphoreSlim TimeEntries
SemaphoreSlim TimeEntries,
SemaphoreSlim SummaryReports,
SemaphoreSlim DetailedReports
) _semaphores = (
new SemaphoreSlim(1, 1),
new SemaphoreSlim(1, 1),
new SemaphoreSlim(1, 1),
new SemaphoreSlim(1, 1),
new SemaphoreSlim(1, 1),
Expand Down Expand Up @@ -220,8 +224,18 @@ internal TogglTrack(PluginInitContext context, Settings settings)
{
string cacheKey = $"SummaryReport{workspaceId}{userId}{(int)reportGrouping}{start.ToString("yyyy-MM-dd")}{end?.ToString("yyyy-MM-dd")}";

if (!force && this._cache.Contains(cacheKey))
bool hasWaited = (this._semaphores.SummaryReports.CurrentCount == 0);
await this._semaphores.SummaryReports.WaitAsync();

if (token.IsCancellationRequested)
{
this._semaphores.SummaryReports.Release();
token.ThrowIfCancellationRequested();
}

if ((!force || hasWaited) && this._cache.Contains(cacheKey))
{
this._semaphores.SummaryReports.Release();
return (SummaryReportResponse?)this._cache.Get(cacheKey);
}

Expand All @@ -240,15 +254,22 @@ internal TogglTrack(PluginInitContext context, Settings settings)
this._cache.Set(cacheKey, summary, DateTimeOffset.Now.AddSeconds(60));
this._cacheKeys.Summary.Add(cacheKey);

token.ThrowIfCancellationRequested();
if (token.IsCancellationRequested)
{
this._semaphores.SummaryReports.Release();
token.ThrowIfCancellationRequested();
}

this._semaphores.SummaryReports.Release();
return summary;
}
catch (Exception exception)
{
token.ThrowIfCancellationRequested();

this._context.API.LogException("TogglTrack", "Failed to fetch summary reports", exception);

this._semaphores.SummaryReports.Release();
return null;
}
}
Expand All @@ -273,8 +294,18 @@ private void _ClearSummaryReportCache()
{
string cacheKey = $"DetailedReport{workspaceId}{userId}{string.Join(",", projectIds ?? new List<long?>())}{start.ToString("yyyy-MM-dd")}{end?.ToString("yyyy-MM-dd")}";

if (!force && this._cache.Contains(cacheKey))
bool hasWaited = (this._semaphores.DetailedReports.CurrentCount == 0);
await this._semaphores.DetailedReports.WaitAsync();

if (token.IsCancellationRequested)
{
this._semaphores.DetailedReports.Release();
token.ThrowIfCancellationRequested();
}

if ((!force || hasWaited) && this._cache.Contains(cacheKey))
{
this._semaphores.DetailedReports.Release();
return (List<DetailedReportTimeEntryGroupResponse>?)this._cache.Get(cacheKey);
}

Expand All @@ -293,15 +324,22 @@ private void _ClearSummaryReportCache()
this._cache.Set(cacheKey, report, DateTimeOffset.Now.AddSeconds(60));
this._cacheKeys.Detailed.Add(cacheKey);

token.ThrowIfCancellationRequested();
if (token.IsCancellationRequested)
{
this._semaphores.DetailedReports.Release();
token.ThrowIfCancellationRequested();
}

this._semaphores.DetailedReports.Release();
return report;
}
catch (Exception exception)
{
token.ThrowIfCancellationRequested();

this._context.API.LogException("TogglTrack", "Failed to fetch detailed reports", exception);

this._semaphores.DetailedReports.Release();
return null;
}
}
Expand Down

0 comments on commit 87a894d

Please sign in to comment.