提交 795ca026 编写于 作者: H Heejae Chang

change timeout to use timer rather than calculate diff from datetime.

上级 7b1ed3f3
......@@ -34,9 +34,12 @@ internal static class RemoteHostOptions
// this is our timeout on how long we will try keep connecting. so far I saw over 2-3 seconds before connection made
// when there are many (over 10+ requests) at the same time. one of reasons of this is we put our service hub process as "Below Normal" priority.
// normally response time is within 10s ms. at most 100ms. if priority is changed to "Normal", most of time 10s ms.
//
// also another reason why timeout is so big is that, if user put this computer sleep, then timeout can happen. so for now, until we have
// sleep aware timer, we put very long timeout for request service (https://github.com/dotnet/roslyn/pull/22151)
[ExportOption]
public static readonly Option<int> RequestServiceTimeoutInMS = new Option<int>(
nameof(InternalFeatureOnOffOptions), nameof(RequestServiceTimeoutInMS), defaultValue: 7 * 24 * 60 * 60 * 1000 /* 7 day */,
nameof(InternalFeatureOnOffOptions), nameof(RequestServiceTimeoutInMS), defaultValue: 7 * 24 * 60 * 60 * 1000 /* 7 days */,
storageLocations: new LocalUserProfileStorageLocation(InternalFeatureOnOffOptions.LocalRegistryPath + nameof(RequestServiceTimeoutInMS)));
// This options allow users to restart OOP when it is killed by users
......
......@@ -176,25 +176,30 @@ private void OnRpcDisconnected(object sender, JsonRpcDisconnectedEventArgs e)
{
const int retry_delayInMS = 50;
var start = DateTime.UtcNow;
while (DateTime.UtcNow - start < timeout)
using (var pooledStopwatch = SharedPools.Default<Stopwatch>().GetPooledObject())
{
cancellationToken.ThrowIfCancellationRequested();
var watch = pooledStopwatch.Object;
watch.Start();
try
{
return await funcAsync().ConfigureAwait(false);
}
catch (TException)
while (watch.Elapsed < timeout)
{
// throw cancellation token if operation is cancelled
cancellationToken.ThrowIfCancellationRequested();
}
// wait for retry_delayInMS before next try
await Task.Delay(retry_delayInMS, cancellationToken).ConfigureAwait(false);
try
{
return await funcAsync().ConfigureAwait(false);
}
catch (TException)
{
// throw cancellation token if operation is cancelled
cancellationToken.ThrowIfCancellationRequested();
}
// wait for retry_delayInMS before next try
await Task.Delay(retry_delayInMS, cancellationToken).ConfigureAwait(false);
ReportTimeout(start);
ReportTimeout(watch);
}
}
// operation timed out, more than we are willing to wait
......@@ -269,6 +274,7 @@ private void OnRpcDisconnected(object sender, JsonRpcDisconnectedEventArgs e)
throw ExceptionUtilities.Unreachable;
}
#region code related to make diagnosis easier later
private static int ReportDetailInfo(IFaultUtility faultUtility)
{
// 0 means send watson, otherwise, cancel watson
......@@ -328,14 +334,14 @@ private static bool ReportNonIOException(Exception ex)
private static readonly TimeSpan s_reportTimeout = TimeSpan.FromMinutes(10);
private static bool s_timeoutReported = false;
private static void ReportTimeout(DateTime start)
private static void ReportTimeout(Stopwatch watch)
{
// if we tried for 10 min and still couldn't connect. NFW some data
if (!s_timeoutReported && (DateTime.UtcNow - start) > s_reportTimeout)
// if we tried for 10 min and still couldn't connect. NFW (non fatal watson) some data
if (!s_timeoutReported && watch.Elapsed > s_reportTimeout)
{
s_timeoutReported = true;
// report service hug logs along with dump
// report service hub logs along with dump
WatsonReporter.Report("RequestServiceAsync Timeout", new Exception("RequestServiceAsync Timeout"), ReportDetailInfo);
}
}
......@@ -355,5 +361,6 @@ private static void ShowInfoBar()
ServicesVSResources.Unfortunately_a_process_used_by_Visual_Studio_has_encountered_an_unrecoverable_error_We_recommend_saving_your_work_and_then_closing_and_restarting_Visual_Studio);
}
}
#endregion
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace Roslyn.Utilities
......@@ -14,6 +15,11 @@ public static PooledObject<StringBuilder> GetPooledObject(this ObjectPool<String
return PooledObject<StringBuilder>.Create(pool);
}
public static PooledObject<Stopwatch> GetPooledObject(this ObjectPool<Stopwatch> pool)
{
return PooledObject<Stopwatch>.Create(pool);
}
public static PooledObject<Stack<TItem>> GetPooledObject<TItem>(this ObjectPool<Stack<TItem>> pool)
{
return PooledObject<Stack<TItem>>.Create(pool);
......@@ -52,6 +58,14 @@ public static StringBuilder AllocateAndClear(this ObjectPool<StringBuilder> pool
return sb;
}
public static Stopwatch AllocateAndClear(this ObjectPool<Stopwatch> pool)
{
var watch = pool.Allocate();
watch.Reset();
return watch;
}
public static Stack<T> AllocateAndClear<T>(this ObjectPool<Stack<T>> pool)
{
var set = pool.Allocate();
......@@ -109,6 +123,17 @@ public static void ClearAndFree(this ObjectPool<StringBuilder> pool, StringBuild
pool.Free(sb);
}
public static void ClearAndFree(this ObjectPool<Stopwatch> pool, Stopwatch watch)
{
if (watch == null)
{
return;
}
watch.Reset();
pool.Free(watch);
}
public static void ClearAndFree<T>(this ObjectPool<HashSet<T>> pool, HashSet<T> set)
{
if (set == null)
......
......@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace Roslyn.Utilities
......@@ -40,6 +41,14 @@ public static PooledObject<StringBuilder> Create(ObjectPool<StringBuilder> pool)
pool,
p => Allocator(p),
(p, sb) => Releaser(p, sb));
}
public static PooledObject<Stopwatch> Create(ObjectPool<Stopwatch> pool)
{
return new PooledObject<Stopwatch>(
pool,
p => Allocator(p),
(p, sb) => Releaser(p, sb));
}
public static PooledObject<Stack<TItem>> Create<TItem>(ObjectPool<Stack<TItem>> pool)
......@@ -94,6 +103,16 @@ private static void Releaser(ObjectPool<StringBuilder> pool, StringBuilder sb)
pool.ClearAndFree(sb);
}
private static Stopwatch Allocator(ObjectPool<Stopwatch> pool)
{
return pool.AllocateAndClear();
}
private static void Releaser(ObjectPool<Stopwatch> pool, Stopwatch sb)
{
pool.ClearAndFree(sb);
}
private static Stack<TItem> Allocator<TItem>(ObjectPool<Stack<TItem>> pool)
{
return pool.AllocateAndClear();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册