提交 bf9eda19 编写于 作者: H Heejae Chang

Merge pull request #3433 from heejaechang/implicitcache2

fix flaky unit test
......@@ -54,11 +54,11 @@ public void ClearImplicitCache()
}
}
public void ClearExpiredImplicitCache(int expirationTimeInMS)
public void ClearExpiredImplicitCache(DateTime expirationTime)
{
lock (_gate)
{
_implicitCache.ClearExpiredItems(expirationTimeInMS);
_implicitCache.ClearExpiredItems(expirationTime);
}
}
......@@ -89,8 +89,8 @@ public IDisposable EnableCaching(ProjectId key)
}
else if (!PartOfP2PReferences(key))
{
_implicitCacheMonitor?.Touch();
_implicitCache.Touch(instance);
_implicitCacheMonitor?.Touch();
}
return instance;
......
......@@ -40,32 +40,32 @@ public bool Empty
public void Touch(object instance)
{
var oldIndex = -1;
var oldTime = Environment.TickCount;
var oldTime = DateTime.UtcNow;
for (var i = 0; i < nodes.Length; i++)
{
if (instance == nodes[i].Data)
{
nodes[i].LastTouchedInMS = Environment.TickCount;
nodes[i].LastTouched = DateTime.UtcNow;
return;
}
if (oldTime >= nodes[i].LastTouchedInMS)
if (oldTime >= nodes[i].LastTouched)
{
oldTime = nodes[i].LastTouchedInMS;
oldTime = nodes[i].LastTouched;
oldIndex = i;
}
}
Contract.Requires(oldIndex >= 0);
nodes[oldIndex] = new Node(instance, Environment.TickCount);
nodes[oldIndex] = new Node(instance, DateTime.UtcNow);
}
public void ClearExpiredItems(int expirationTimeInMS)
public void ClearExpiredItems(DateTime expirationTime)
{
for (var i = 0; i < nodes.Length; i++)
{
if (nodes[i].Data != null && nodes[i].LastTouchedInMS < expirationTimeInMS)
if (nodes[i].Data != null && nodes[i].LastTouched < expirationTime)
{
nodes[i] = default(Node);
}
......@@ -80,12 +80,12 @@ public void Clear()
private struct Node
{
public readonly object Data;
public int LastTouchedInMS;
public DateTime LastTouched;
public Node(object data, int lastTouchedInMS)
public Node(object data, DateTime lastTouched)
{
Data = data;
LastTouchedInMS = lastTouchedInMS;
LastTouched = lastTouched;
}
}
}
......@@ -108,7 +108,7 @@ private class ImplicitCacheMonitor : IdleProcessor
protected override Task ExecuteAsync()
{
_owner.ClearExpiredImplicitCache(Environment.TickCount - BackOffTimeSpanInMS);
_owner.ClearExpiredImplicitCache(DateTime.UtcNow - TimeSpan.FromMilliseconds(BackOffTimeSpanInMS));
return SpecializedTasks.EmptyTask;
}
......
......@@ -120,14 +120,35 @@ public void TestImplicitCacheKeepsObjectAlive1()
public void TestImplicitCacheMonitoring()
{
var cacheService = new ProjectCacheHostServiceFactory.ProjectCacheService(null, 10, forceCleanup: true);
var weak = PutObjectInImplicitCache(cacheService);
var timeout = TimeSpan.FromSeconds(10);
var current = DateTime.UtcNow;
do
{
Thread.Sleep(100);
CollectGarbage();
if (DateTime.UtcNow - current > timeout)
{
break;
}
}
while (weak.IsAlive);
Assert.False(weak.IsAlive);
GC.KeepAlive(cacheService);
}
private static WeakReference PutObjectInImplicitCache(ProjectCacheHostServiceFactory.ProjectCacheService cacheService)
{
var instance = new object();
var weak = new WeakReference(instance);
cacheService.CacheObjectIfCachingEnabledForKey(ProjectId.CreateNewId(), (object)null, instance);
instance = null;
Thread.Sleep(100);
CollectGarbage();
Assert.False(weak.IsAlive);
GC.KeepAlive(cacheService);
return weak;
}
[Fact]
......@@ -224,9 +245,12 @@ private class Owner : ICachedObjectOwner
private static void CollectGarbage()
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
for (var i = 0; i < 10; i++)
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册