You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@trafficserver.apache.org by mark <mn...@haskalah.org> on 2011/03/18 13:28:05 UTC

User callback on connect failure

I've been trying to implement the ability to allow a user-defined 
callback for each failure to an origin server or parent proxy. The idea 
being that when ATS' built-in failover mechanisms are exhausted and it 
is about to send an error response to the user, a plugin author might be 
able to (heuristically?) determine a different path to take in order to 
retrieve the content.

I've been poking around the code a bit and tried to implement at least 
an internal hook, but to no avail.

Here's what i tried to do (using a 5-day old trunk):

--- ../tsorig/proxy/http/HttpTransact.cc    2011-03-09 
21:43:58.000000000 +0000
+++ proxy/http/HttpTransact.cc    2011-03-18 12:05:48.000000000 +0000
@@ -33,6 +33,7 @@
  #include "HttpDebugNames.h"
  #include "time.h"
  #include "ParseRules.h"
+#include <string.h>
  #include "HTTP.h"
  #include "HdrUtils.h"
  #include "HttpMessageBody.h"
@@ -47,6 +48,7 @@
  #include "StatPages.h"
  #include "HttpClientSession.h"
  #include "I_Machine.h"
+#include <pcre.h>

  static const char *URL_MSG = "Unable to process requested URL.\n";

@@ -278,6 +280,36 @@ is_negative_caching_appropriate(HttpTran
  }

  inline static HttpTransact::LookingUp_t
+maybe_override_retry(HttpTransact::State *s, HttpTransact::LookingUp_t in)
+{
+    static int counter = 0;
+    Debug("mndebug(override_retry)", "begin. Counter is %d", counter);
+    if(counter < 5) {
+        counter++;
+    } else {
+        counter = 0;
+        Debug("mndebug(override_retry)", "arbitrarily returning same 
input to avoid infinite looping");
+        return in;
+    }
+    if (in == HttpTransact::HOST_NONE || HttpTransact::ORIGIN_SERVER) {
+        Debug("mndebug(override_retry", "Trying to override.. wish me 
luck");
+        s->parent_result.hostname = "127.0.0.1";
+        s->parent_result.port = 54321;
+        s->parent_result.r = PARENT_SPECIFIED;
+        s->parent_info.name = (char*)"127.0.0.1";
+        s->parent_info.port = 54321;
+        update_current_info(
+ &s->current, &s->parent_info, HttpTransact::PARENT_PROXY,
+                (s->current.attempts)++);
+        in = HttpTransact::PARENT_PROXY;
+        ink_debug_assert(s->current.request_to == 
HttpTransact::PARENT_PROXY);
+    }
+    Debug("mndebug(override_retry)", "Returning..");
+    return in;
+}
+
+
+inline static HttpTransact::LookingUp_t
  find_server_and_update_current_info(HttpTransact::State* s)
  {
    URL *url = s->hdr_info.client_request.url_get();
@@ -1248,7 +1280,6 @@ HttpTransact::HandleRequest(State* s)
      if ((int32_t) addr != -1) {
        s->request_data.dest_ip = addr;
      }
-
      if (s->parent_params->parentExists(&s->request_data)) {
        // If the proxy is behind and firewall and there is no
        //  DNS service available, we just want to forward the request
@@ -1279,8 +1310,6 @@ HttpTransact::HandleRequest(State* s)
    if (s->txn_conf->cache_http && s->redirect_info.redirect_in_process 
&& s->state_machine->enable_redirection) {
      TRANSACT_RETURN(CACHE_LOOKUP, NULL);
    }
-
-
    if (s->force_dns) {
      TRANSACT_RETURN(DNS_LOOKUP, OSDNSLookup);   // After handling the 
request, DNS is done.
    } else {
@@ -3366,6 +3395,7 @@ HttpTransact::handle_response_from_icp_s
  #endif //INK_NO_ICP


+
  ///////////////////////////////////////////////////////////////////////////////
  // Name       : handle_response_from_parent
  // Description: response came from a parent proxy
@@ -3452,9 +3482,11 @@ HttpTransact::handle_response_from_paren
          s->parent_result.r = PARENT_FAIL;
          next_lookup = find_server_and_update_current_info(s);
        }
-
        // We have either tried to find a new parent or failed over to the
        //   origin server
+
+      //See if we can override this with maybe_override_retry();
+      next_lookup = maybe_override_retry(s, next_lookup);
        switch (next_lookup) {
        case PARENT_PROXY:
          ink_debug_assert(s->current.request_to == PARENT_PROXY);
@@ -7646,6 +7678,12 @@ HttpTransact::handle_parent_died(State*
  void
  HttpTransact::handle_server_died(State* s)
  {
+  LookingUp_t retry_type = maybe_override_retry(s, 
HttpTransact::HOST_NONE);
+  if (retry_type == PARENT_PROXY) {
+
+      TRANSACT_RETURN(DNS_LOOKUP, PPDNSLookup);
+      return;
+  }
    const char *reason = NULL;
    const char *body_type = "UNKNOWN";
    HTTPStatus status = HTTP_STATUS_BAD_GATEWAY;