2016-05-13 15 views
1

Wir haben eine Web-API 2-Anwendung, die Strathweb.CacheOutput.WebApi2 für das Zwischenspeichern verwendet.Erkennen, ob die Web-API-Anforderung vom Cache bedient wird

Kurze Frage: Gibt es eine Möglichkeit, in Application_LogRequest (oder irgendwo, wirklich) zu erkennen, ob eine Anfrage von Cache gedient wurde?

Lange Frage: In letzter Zeit haben wir uns die Leistung angesehen und sehen, welche API-Aufrufe wir verbessern können. Ich zog eine Liste aus unseren Logs (inklusive Dauer), um zu sehen, was die schlimmsten Übeltäter sind. Unter den schlimmsten Tätern verstehe ich die längste durchschnittliche Dauer und/oder die meisten Anrufe.

Aber die Zahlen sind irreführend, weil die zwischengespeicherten Anforderungen in den Statistiken enthalten sind. Zwischengespeicherte Anforderungen werden in der Regel in einer halben Sekunde oder weniger geliefert, sodass sie die durchschnittliche Dauer verringern. Wenn ein bestimmter Anruf ausgeführt wird, sagen wir 1000 mal pro Minute, aber 999 davon werden zwischengespeichert, ist es mir egal.

Also möchte ich ein Flag in meinem Protokoll hinzufügen, das angibt, ob die Anfrage vom Cache bedient wurde, damit ich diese ausschließen kann. All unsere Protokollierung erfolgt im Application_LogRequest-Ereignis. Aber selbst wenn ich es irgendwo anders finden kann, kann ich einen Wert in HttpContext.Current.Items speichern, den ich später abrufen kann.

Antwort

1

Strathweb CacheOutputAttribute fügt keine verlässlichen Informationen in http-Antworten oder anderswo hinzu, um zu wissen, ob die Antwort vom Cache geliefert wurde oder nicht.

Sie können davon ableiten, um dies zu tun, dann ersetzen Sie alle Ihre Verwendung von CacheOutputAttribute durch Ihre eigenen.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
public class YourCustomizedCacheOutputAttribute : CacheOutputAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     base.OnActionExecuting(actionContext); 
     // If response is set, it has been retrieved from cache. 
     actionContext.Request.Properties["yourCacheHitKey"] = 
      actionContext.Response != null; 
    } 
} 

Natürlich nutzen, um etwas anderes als HttpRequestMessage.Properties wenn, wo Sie Sie sich keinen Zugriff darauf haben.

Sie mit gutem Beispiel einige benutzerdefinierte Header in Antwort hinzufügen kann, ist für Sie kein Problem, dass, um Browser, wenn undicht:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
public class YourCustomizedCacheOutputAttribute : CacheOutputAttribute 
{ 
    // "X-" prefix is deprecated, but the rational behind this is about wannabe 
    // standard header. I do not intend this one to become standard for anything. 
    private const string _cacheHeader = "X-Cache"; 
    protected override void ApplyCacheHeaders(HttpResponseMessage response, 
     CacheTime cacheTime) 
    { 
     base.ApplyCacheHeaders(response, cacheTime); 

     if (response.Headers.Contains(_cacheHeader)) 
      return; 

     // At this point, we do not know. miss by default. 
     response.Headers.Add(_cacheHeader, "miss"); 
    } 

    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     base.OnActionExecuting(actionContext); 
     if (actionContext.Response == null) 
      return; 

     // Response has been retrieved from cache. 
     // Headers.Remove does not fail if not already there. 
     response.Headers.Remove(_cacheHeader); 
     actionContext.Response.Headers.Add(_cacheHeader, "hit"); 
    } 
} 
+0

Thank you! Ich habe auf eine Methode gehofft, bei der nichts übergangen werden musste, aber das sieht nicht so aus. Danke für den Beispielcode. Das wird definitiv helfen! –