Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Commit f6f7b37

Browse files
authored
Merge pull request #627 from github-for-unity/1.0rc/fixes/more-cache-refresh
Cache refresh fixes for 1.0rc/master
2 parents befcbf7 + 76d9f61 commit f6f7b37

22 files changed

+315
-292
lines changed

src/GitHub.Api/Application/ApplicationManagerBase.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ public void Run(bool firstRun)
5555
{
5656
Logger.Trace("Run - CurrentDirectory {0}", NPath.CurrentDirectory);
5757

58+
isBusy = true;
59+
5860
var gitExecutablePath = SystemSettings.Get(Constants.GitInstallPathKey)?.ToNPath();
5961
if (gitExecutablePath.HasValue && gitExecutablePath.Value.FileExists()) // we have a git path
6062
{
@@ -65,7 +67,6 @@ public void Run(bool firstRun)
6567
{
6668
Logger.Trace("No git path found in settings");
6769

68-
isBusy = true;
6970
var initEnvironmentTask = new ActionTask<NPath>(CancellationToken,
7071
(b, path) => InitializeEnvironment(path)) { Affinity = TaskAffinity.UI };
7172
var findExecTask = new FindExecTask("git", CancellationToken)
@@ -81,7 +82,6 @@ public void Run(bool firstRun)
8182
//Logger.Warning("FindExecTask Failure");
8283
Logger.Error("Git not found");
8384
}
84-
isBusy = false;
8585
});
8686

8787
var gitInstaller = new GitInstaller(Environment, CancellationToken);
@@ -91,7 +91,7 @@ public void Run(bool firstRun)
9191
setupTask.Progress(progressReporter.UpdateProgress);
9292
setupTask.OnEnd += (thisTask, result, success, exception) =>
9393
{
94-
if (success && result != null)
94+
if (success && result.IsInitialized)
9595
thisTask.Then(initEnvironmentTask);
9696
else
9797
thisTask.Then(findExecTask);
@@ -248,7 +248,7 @@ public void Dispose()
248248
public ISettings SystemSettings { get; protected set; }
249249
public ISettings UserSettings { get; protected set; }
250250
public IUsageTracker UsageTracker { get; protected set; }
251-
public bool IsBusy { get { return isBusy || (RepositoryManager?.IsBusy ?? false); } }
251+
public bool IsBusy { get { return isBusy; } }
252252
protected TaskScheduler UIScheduler { get; private set; }
253253
protected SynchronizationContext SynchronizationContext { get; private set; }
254254
protected IRepositoryManager RepositoryManager { get { return repositoryManager; } }

src/GitHub.Api/Cache/CacheContainer.cs

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Globalization;
34
using GitHub.Logging;
45

56
namespace GitHub.Unity
@@ -47,10 +48,11 @@ public IManagedCache GetCache(CacheType cacheType)
4748
return caches[cacheType].Value;
4849
}
4950

50-
public void CheckAndRaiseEventsIfCacheNewer(CacheUpdateEvent cacheUpdateEvent)
51+
public void CheckAndRaiseEventsIfCacheNewer(CacheType cacheType, CacheUpdateEvent cacheUpdateEvent)
5152
{
52-
var cache = GetCache(cacheUpdateEvent.cacheType);
53-
if (cache.LastUpdatedAt != cacheUpdateEvent.UpdatedTime)
53+
var cache = GetCache(cacheType);
54+
var needsInvalidation = cache.ValidateData();
55+
if (!cacheUpdateEvent.IsInitialized || !needsInvalidation || cache.LastUpdatedAt != cacheUpdateEvent.UpdatedTime)
5456
{
5557
OnCacheUpdated(cache.CacheType, cache.LastUpdatedAt);
5658
}
@@ -98,4 +100,89 @@ public void Dispose()
98100
public IGitUserCache GitUserCache { get { return (IGitUserCache)caches[CacheType.GitUser].Value; } }
99101
public IRepositoryInfoCache RepositoryInfoCache { get { return (IRepositoryInfoCache)caches[CacheType.RepositoryInfo].Value; } }
100102
}
103+
104+
[Serializable]
105+
public struct CacheUpdateEvent
106+
{
107+
[NonSerialized] private DateTimeOffset? updatedTimeValue;
108+
public string updatedTimeString;
109+
public CacheType cacheType;
110+
111+
public CacheUpdateEvent(CacheType type, DateTimeOffset when)
112+
{
113+
if (type == CacheType.None) throw new ArgumentOutOfRangeException(nameof(type));
114+
115+
cacheType = type;
116+
updatedTimeValue = when;
117+
updatedTimeString = when.ToString(Constants.Iso8601Format);
118+
}
119+
120+
public override int GetHashCode()
121+
{
122+
int hash = 17;
123+
hash = hash * 23 + cacheType.GetHashCode();
124+
hash = hash * 23 + (updatedTimeString?.GetHashCode() ?? 0);
125+
return hash;
126+
}
127+
128+
public override bool Equals(object other)
129+
{
130+
if (other is CacheUpdateEvent)
131+
return Equals((CacheUpdateEvent)other);
132+
return false;
133+
}
134+
135+
public bool Equals(CacheUpdateEvent other)
136+
{
137+
return
138+
cacheType == other.cacheType &&
139+
String.Equals(updatedTimeString, other.updatedTimeString)
140+
;
141+
}
142+
143+
public static bool operator ==(CacheUpdateEvent lhs, CacheUpdateEvent rhs)
144+
{
145+
// If both are null, or both are same instance, return true.
146+
if (ReferenceEquals(lhs, rhs))
147+
return true;
148+
149+
// If one is null, but not both, return false.
150+
if (((object)lhs == null) || ((object)rhs == null))
151+
return false;
152+
153+
// Return true if the fields match:
154+
return lhs.Equals(rhs);
155+
}
156+
157+
public static bool operator !=(CacheUpdateEvent lhs, CacheUpdateEvent rhs)
158+
{
159+
return !(lhs == rhs);
160+
}
161+
162+
public DateTimeOffset UpdatedTime
163+
{
164+
get
165+
{
166+
if (!updatedTimeValue.HasValue)
167+
{
168+
DateTimeOffset result;
169+
if (DateTimeOffset.TryParseExact(updatedTimeString, Constants.Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.None, out result))
170+
{
171+
updatedTimeValue = result;
172+
}
173+
else
174+
{
175+
updatedTimeValue = DateTimeOffset.MinValue;
176+
updatedTimeString = updatedTimeValue.Value.ToString(Constants.Iso8601Format);
177+
}
178+
}
179+
180+
return updatedTimeValue.Value;
181+
}
182+
}
183+
184+
public bool IsInitialized => cacheType != CacheType.None;
185+
186+
public string UpdatedTimeString => updatedTimeString;
187+
}
101188
}

src/GitHub.Api/Cache/CacheInterfaces.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace GitHub.Unity
55
{
66
public enum CacheType
77
{
8+
None,
89
RepositoryInfo,
910
Branches,
1011
GitLog,
@@ -29,7 +30,7 @@ public interface ICacheContainer : IDisposable
2930
void ValidateAll();
3031
void InvalidateAll();
3132
IManagedCache GetCache(CacheType cacheType);
32-
void CheckAndRaiseEventsIfCacheNewer(CacheUpdateEvent cacheUpdateEvent);
33+
void CheckAndRaiseEventsIfCacheNewer(CacheType cacheType, CacheUpdateEvent cacheUpdateEvent);
3334
}
3435

3536
public interface IManagedCache

src/GitHub.Api/Git/IRepository.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public interface IRepository : IEquatable<IRepository>, IDisposable
2121
ITask RequestLock(string file);
2222
ITask ReleaseLock(string file, bool force);
2323
ITask DiscardChanges(GitStatusEntry[] discardEntries);
24-
void CheckAndRaiseEventsIfCacheNewer(CacheUpdateEvent cacheUpdateEvent);
24+
void CheckAndRaiseEventsIfCacheNewer(CacheType cacheType, CacheUpdateEvent cacheUpdateEvent);
2525

2626
/// <summary>
2727
/// Gets the name of the repository.
@@ -60,6 +60,7 @@ public interface IRepository : IEquatable<IRepository>, IDisposable
6060
List<GitLock> CurrentLocks { get; }
6161
string CurrentBranchName { get; }
6262
List<GitLogEntry> CurrentLog { get; }
63+
bool IsBusy { get; }
6364

6465
event Action<CacheUpdateEvent> LogChanged;
6566
event Action<CacheUpdateEvent> TrackingStatusChanged;

src/GitHub.Api/Git/Repository.cs

Lines changed: 19 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ public Repository(NPath localPath, ICacheContainer container)
5050
RemoteBranchListChanged?.Invoke(cacheUpdateEvent);
5151
LocalAndRemoteBranchListChanged?.Invoke(cacheUpdateEvent);
5252
}},
53-
{ CacheType.GitAheadBehind, TrackingStatusChanged.SafeInvoke },
54-
{ CacheType.GitLocks, LocksChanged.SafeInvoke },
55-
{ CacheType.GitLog, LogChanged.SafeInvoke },
56-
{ CacheType.GitStatus, StatusEntriesChanged.SafeInvoke },
53+
{ CacheType.GitAheadBehind, c => TrackingStatusChanged?.Invoke(c) },
54+
{ CacheType.GitLocks, c => LocksChanged?.Invoke(c) },
55+
{ CacheType.GitLog, c => LogChanged?.Invoke(c) },
56+
{ CacheType.GitStatus, c => StatusEntriesChanged?.Invoke(c) },
5757
{ CacheType.GitUser, cacheUpdateEvent => { } },
5858
{ CacheType.RepositoryInfo, cacheUpdateEvent => {
5959
CurrentBranchChanged?.Invoke(cacheUpdateEvent);
@@ -64,7 +64,10 @@ public Repository(NPath localPath, ICacheContainer container)
6464

6565
cacheContainer = container;
6666
cacheContainer.CacheInvalidated += CacheHasBeenInvalidated;
67-
cacheContainer.CacheUpdated += (cacheType, offset) => cacheUpdateEvents[cacheType](new CacheUpdateEvent(cacheType, offset));
67+
cacheContainer.CacheUpdated += (cacheType, offset) =>
68+
{
69+
cacheUpdateEvents[cacheType](new CacheUpdateEvent(cacheType, offset));
70+
};
6871
}
6972

7073
public void Initialize(IRepositoryManager repositoryManager, ITaskManager taskManager)
@@ -117,7 +120,7 @@ public ITask SetupRemote(string remote, string remoteUrl)
117120
public ITask ReleaseLock(string file, bool force) => repositoryManager.UnlockFile(file, force);
118121
public ITask DiscardChanges(GitStatusEntry[] gitStatusEntry) => repositoryManager.DiscardChanges(gitStatusEntry);
119122

120-
public void CheckAndRaiseEventsIfCacheNewer(CacheUpdateEvent cacheUpdateEvent) => cacheContainer.CheckAndRaiseEventsIfCacheNewer(cacheUpdateEvent);
123+
public void CheckAndRaiseEventsIfCacheNewer(CacheType cacheType, CacheUpdateEvent cacheUpdateEvent) => cacheContainer.CheckAndRaiseEventsIfCacheNewer(cacheType, cacheUpdateEvent);
121124

122125

123126
/// <summary>
@@ -154,11 +157,14 @@ public bool Equals(IRepository other)
154157

155158
private void RefreshCache(CacheType cacheType)
156159
{
157-
var cache = cacheContainer.GetCache(cacheType);
158-
// if the cache has valid data, we need to force an invalidation to refresh it
159-
// if it doesn't have valid data, it will trigger an invalidation automatically
160-
if (cache.ValidateData())
161-
cache.InvalidateData();
160+
taskManager.RunInUI(() =>
161+
{
162+
var cache = cacheContainer.GetCache(cacheType);
163+
// if the cache has valid data, we need to force an invalidation to refresh it
164+
// if it doesn't have valid data, it will trigger an invalidation automatically
165+
if (cache.ValidateData())
166+
cache.InvalidateData();
167+
});
162168
}
163169

164170
private void CacheHasBeenInvalidated(CacheType cacheType)
@@ -362,6 +368,7 @@ public string Name
362368
public NPath LocalPath { get; private set; }
363369
public string Owner => CloneUrl?.Owner ?? null;
364370
public bool IsGitHub => HostAddress.IsGitHubDotCom(CloneUrl);
371+
public bool IsBusy => repositoryManager?.IsBusy ?? false;
365372

366373
internal string DebuggerDisplay => String.Format(CultureInfo.InvariantCulture,
367374
"{0} Owner: {1} Name: {2} CloneUrl: {3} LocalPath: {4} Branch: {5} Remote: {6}", GetHashCode(), Owner, Name,
@@ -398,17 +405,7 @@ public User(ICacheContainer cacheContainer)
398405
cacheContainer.CacheUpdated += (type, dt) => { if (type == CacheType.GitUser) CacheHasBeenUpdated(dt); };
399406
}
400407

401-
public void CheckUserChangedEvent(CacheUpdateEvent cacheUpdateEvent)
402-
{
403-
var managedCache = cacheContainer.GitUserCache;
404-
var raiseEvent = managedCache.LastUpdatedAt != cacheUpdateEvent.UpdatedTime;
405-
406-
Logger.Trace("Check GitUserCache CacheUpdateEvent Current:{0} Check:{1} Result:{2}", managedCache.LastUpdatedAt,
407-
cacheUpdateEvent.UpdatedTime, raiseEvent);
408-
409-
if (raiseEvent)
410-
CacheHasBeenUpdated(managedCache.LastUpdatedAt);
411-
}
408+
public void CheckUserChangedEvent(CacheUpdateEvent cacheUpdateEvent) => cacheContainer.CheckAndRaiseEventsIfCacheNewer(CacheType.GitUser, cacheUpdateEvent);
412409

413410
public void Initialize(IGitClient client)
414411
{
@@ -486,89 +483,4 @@ public string Email
486483

487484
protected static ILogging Logger { get; } = LogHelper.GetLogger<User>();
488485
}
489-
490-
[Serializable]
491-
public struct CacheUpdateEvent
492-
{
493-
[NonSerialized] private DateTimeOffset? updatedTimeValue;
494-
public string updatedTimeString;
495-
public CacheType cacheType;
496-
497-
public CacheUpdateEvent(CacheType type, DateTimeOffset when)
498-
{
499-
cacheType = type;
500-
updatedTimeValue = when;
501-
updatedTimeString = when.ToString(Constants.Iso8601Format);
502-
}
503-
504-
public override int GetHashCode()
505-
{
506-
int hash = 17;
507-
hash = hash * 23 + cacheType.GetHashCode();
508-
hash = hash * 23 + (updatedTimeString?.GetHashCode() ?? 0);
509-
return hash;
510-
}
511-
512-
public override bool Equals(object other)
513-
{
514-
if (other is CacheUpdateEvent)
515-
return Equals((CacheUpdateEvent)other);
516-
return false;
517-
}
518-
519-
public bool Equals(CacheUpdateEvent other)
520-
{
521-
return
522-
cacheType == other.cacheType &&
523-
String.Equals(updatedTimeString, other.updatedTimeString)
524-
;
525-
}
526-
527-
public static bool operator ==(CacheUpdateEvent lhs, CacheUpdateEvent rhs)
528-
{
529-
// If both are null, or both are same instance, return true.
530-
if (ReferenceEquals(lhs, rhs))
531-
return true;
532-
533-
// If one is null, but not both, return false.
534-
if (((object)lhs == null) || ((object)rhs == null))
535-
return false;
536-
537-
// Return true if the fields match:
538-
return lhs.Equals(rhs);
539-
}
540-
541-
public static bool operator !=(CacheUpdateEvent lhs, CacheUpdateEvent rhs)
542-
{
543-
return !(lhs == rhs);
544-
}
545-
546-
public DateTimeOffset UpdatedTime
547-
{
548-
get
549-
{
550-
if (!updatedTimeValue.HasValue)
551-
{
552-
DateTimeOffset result;
553-
if (DateTimeOffset.TryParseExact(updatedTimeString, Constants.Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.None, out result))
554-
{
555-
updatedTimeValue = result;
556-
}
557-
else
558-
{
559-
UpdatedTime = DateTimeOffset.MinValue;
560-
}
561-
}
562-
563-
return updatedTimeValue.Value;
564-
}
565-
set
566-
{
567-
updatedTimeValue = value;
568-
updatedTimeString = value.ToString(Constants.Iso8601Format);
569-
}
570-
}
571-
572-
public string UpdatedTimeString => updatedTimeString;
573-
}
574486
}

0 commit comments

Comments
 (0)