2017-07-21 89 views
3

考慮而觀察到的代表傳入的請求......使用測量響應時間觀測

interface IRequest 
{ 
    string Id { get; } 
} 

IObservable<IRequest> requests; 

和可觀b和反應......

IObservable<string> responses; 

我需要測量才能產生時間響應。我目前的解決方案如下所示。這工作,但我不知道這是否可以簡化或實施更精簡。我還擔心實際響應時間([GEN])與觀測響應時間([OBS])之間的偏差,如果generatedResponseTime設置爲低於50ms,則響應時間變得非常重要。

class Program 
{ 
    public class Request 
    { 
     public string Id { get; set; } 
    } 

    static void Main(string[] args) 
    { 
     var generatedResponseTime = 100; 

     var responseSub = new Subject<string>(); 

     IObservable<Request> requests = Observable.Interval(TimeSpan.FromMilliseconds(1000)) 
      .Select(x=> new Request { Id = x.ToString("d") }); 

     IObservable<string> responses = responseSub.AsObservable(); 

     var responseTime = requests 
      .Where(x => !string.IsNullOrEmpty(x.Id)) 
      .Select(req => new { Id = req.Id, Start = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }) 
      .SelectMany(req => responses 
       .Where(reqId => reqId == req.Id) 
       .Select(_ => new { RequestId = req.Id, ResponseTime = (int)(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - req.Start) }) 
       .Take(1)) 
      .Publish() 
      .RefCount(); 

     requests.ObserveOn(TaskPoolScheduler.Default) 
      .Subscribe(req => 
      { 
       Console.WriteLine($"[GEN] {req.Id} = {generatedResponseTime} ms"); 

       Thread.Sleep(generatedResponseTime); 
       responseSub.OnNext(req.Id); 
      }); 

     responseTime.Subscribe(x => Console.WriteLine($"[OBS] {x.RequestId} = {x.ResponseTime} ms")); 

     Console.ReadLine(); 
    } 
} 
+0

您能否爲此提供[mcve]?我可以複製,粘貼和運行以查看代碼的工作方式? – Enigmativity

+0

這是我見過的最好的[mcve]之一。 +1! – Enigmativity

+0

爲什麼你有'.Publish().RecCount()'? – Enigmativity

回答

3

下面是使用一些內置操作符的替代方法。也沒有在解決方案中的多個訂閱的問題:

var responseTime2 = requests 
    .Timestamp() 
    .Join(responses.Timestamp(), 
     request => Observable.Never<Unit>(), //timeout criteria 
     response => Observable.Empty<Unit>(), 
     (request, response) => (request: request, response: response) 
    ) 
    .Where(t => t.request.Value.Id == t.response.Value) 
    .Select(t => t.response.Timestamp.ToUnixTimeMilliseconds() - t.request.Timestamp.ToUnixTimeMilliseconds()) 

如果您有任何形式的對請求超時的標準,那麼這將是從性能的角度有助於把那個地方的評論表示。否則,隨着時間的推移,Join/Where組合的表現將會惡化。