You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2015/06/07 06:15:27 UTC

trafficserver git commit: Numerous fixes - can do range then full request.

Repository: trafficserver
Updated Branches:
  refs/heads/ts-974-5-3-x ff379f67a -> ebd737154


Numerous fixes - can do range then full request.


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/ebd73715
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/ebd73715
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/ebd73715

Branch: refs/heads/ts-974-5-3-x
Commit: ebd737154e7799c1bf82531042d16586c85f50e3
Parents: ff379f6
Author: Alan M. Carroll <so...@yahoo-inc.com>
Authored: Sat Jun 6 23:15:07 2015 -0500
Committer: Alan M. Carroll <so...@yahoo-inc.com>
Committed: Sat Jun 6 23:15:07 2015 -0500

----------------------------------------------------------------------
 iocore/cache/CacheRead.cc  |  4 +++
 iocore/cache/CacheWrite.cc | 54 +++++++++++++++++++++++++++++------------
 proxy/hdrs/HTTP.cc         |  7 ++++--
 proxy/hdrs/HTTP.h          |  5 ++++
 proxy/http/HttpSM.cc       | 22 +++++++++++------
 proxy/http/HttpTransact.cc |  9 ++++---
 proxy/http/HttpTransact.h  |  4 +--
 7 files changed, 74 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ebd73715/iocore/cache/CacheRead.cc
----------------------------------------------------------------------
diff --git a/iocore/cache/CacheRead.cc b/iocore/cache/CacheRead.cc
index 52a395c..915d269 100644
--- a/iocore/cache/CacheRead.cc
+++ b/iocore/cache/CacheRead.cc
@@ -313,6 +313,7 @@ CacheVC::openReadFromWriter(int event, Event *e)
     alternate.copy_shallow(od->vector.get(alternate_index));
     key = earliest_key = alternate.object_key_get();
     doc_len = alternate.object_size_get();
+    Debug("amc", "[openReadFromWriter] - setting alternate from write_vc %p to #%d : %p", write_vc, alternate_index, alternate.m_alt);
     MUTEX_RELEASE(lock_od);
     SET_HANDLER(&CacheVC::openReadStartEarliest);
     return openReadStartEarliest(event, e);
@@ -324,6 +325,7 @@ CacheVC::openReadFromWriter(int event, Event *e)
         SET_HANDLER(&CacheVC::openReadFromWriterFailure);
         return openReadFromWriterFailure(CACHE_EVENT_OPEN_READ_FAILED, reinterpret_cast<Event *>(-ECACHE_ALT_MISS));
       }
+      Debug("amc", "[openReadFromWriter] select alt: %d %p (current %p)", alternate_index, od->vector.get(alternate_index)->m_alt, alternate.m_alt);
       write_vector = &od->vector;
     } else {
       alternate_index = 0;
@@ -904,6 +906,7 @@ CacheVC::openReadVecWrite(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */
       if (od->move_resident_alt)
         dir_insert(&od->single_doc_key, vol, &od->single_doc_dir);
       int alt_ndx = HttpTransactCache::SelectFromAlternates(write_vector, &request, params);
+      Debug("amc", "[openReadVecWrite] select alt: %d %p (current %p)", alt_ndx, write_vector->get(alt_ndx)->m_alt, alternate.m_alt);
       vol->close_write(this);
       if (alt_ndx >= 0) {
         vector.clear();
@@ -1038,6 +1041,7 @@ CacheVC::openReadStartHead(int event, Event *e)
           err = ECACHE_ALT_MISS;
           goto Ldone;
         }
+        Debug("amc", "[openReadStartHead] select alt: %d %p (current %p, od %p)", alternate_index, vector.get(alternate_index)->m_alt, alternate.m_alt, od);
       } else if (CACHE_ALT_INDEX_DEFAULT == (alternate_index = get_alternate_index(&vector, earliest_key)))
         alternate_index = 0;
       alternate_tmp = vector.get(alternate_index);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ebd73715/iocore/cache/CacheWrite.cc
----------------------------------------------------------------------
diff --git a/iocore/cache/CacheWrite.cc b/iocore/cache/CacheWrite.cc
index 0bd829c..f22f901 100644
--- a/iocore/cache/CacheWrite.cc
+++ b/iocore/cache/CacheWrite.cc
@@ -1398,16 +1398,29 @@ CacheVC::openWriteInit(int eid, Event* event)
       return EVENT_CONT;
     }
 
-    // If we're not already in the alt vector, insert.
-    if (earliest_key != alternate.object_key_get()) {
+    if (alternate.valid() && earliest_key != alternate.object_key_get()) {
+      // When the VC is created it sets up for a new alternate write. If we're back filling we
+      // need to tweak that back to the existing alternate.
       Debug("amc", "[CacheVC::openWriteInit] updating earliest key from alternate");
       alternate.object_key_get(&earliest_key);
     }
+    // Get synchronized with the OD vector.
     if (-1 == (alternate_index = get_alternate_index(write_vector, earliest_key))) {
-      alternate_index = write_vector->insert(&alternate);
+      Debug("amc", "[openWriteInit] alt not found, inserted");
+      alternate_index = write_vector->insert(&alternate); // not there, add it
+    } else {
+      HTTPInfo* base = write_vector->get(alternate_index);
+      if (!base->is_writeable()) {
+        // The alternate instance is mapped directly on a read buffer, which we can't modify.
+        // It must be replaced with a live, mutable one.
+        Debug("amc", "Updating OD vector element %d : 0x%p with mutable version %p", alternate_index, base, alternate.m_alt);
+        alternate.copy(base); // make a local copy
+        base->copy_shallow(&alternate); // paste the mutable copy back.
+      }
     }
     // mark us as an writer.
     write_vector->data[alternate_index]._writers.push(this);
+    alternate.copy_shallow(write_vector->get(alternate_index));
 
     if (this == od->open_writer) {
       od->open_writer = NULL;
@@ -1530,9 +1543,12 @@ Lagain:
       not_writing = true;
     } else if (alternate.is_frag_cached(fragment)) {
       not_writing = true;
-      resp_range.consume(length); // just drop it.
       Debug("amc", "Fragment %d already cached", fragment);
-      // Need to consume the actual data too (in blocks/offset).
+      // Consume the data, as we won't be using it.
+      resp_range.consume(write_len);
+      blocks = iobufferblock_skip(blocks, &offset, &length, write_len);
+      // need to kick start things again or we'll stall.
+      return this->handleEvent(EVENT_IMMEDIATE);
     } else {
       od->write_active(earliest_key, this, write_pos);
     }
@@ -1851,17 +1867,23 @@ Cache::open_write(Continuation *cont, CacheKey *key, CacheHTTPInfo *info, time_t
   ProxyMutex *mutex = cont->mutex;
   c->vio.op = VIO::WRITE;
   c->first_key = *key;
-  /*
-     The transition from single fragment document to a multi-fragment document
-     would cause a problem if the key and the first_key collide. In case of
-     a collision, old vector data could be served to HTTP. Need to avoid that.
-     Also, when evacuating a fragment, we have to decide if its the first_key
-     or the earliest_key based on the dir_tag.
-   */
-  do {
-    rand_CacheKey(&c->key, cont->mutex);
-  } while (DIR_MASK_TAG(c->key.slice32(2)) == DIR_MASK_TAG(c->first_key.slice32(2)));
-  c->earliest_key = c->key;
+  if (info) {
+    info->object_key_get(&c->key);
+    c->earliest_key = c->key;
+  } else {
+    /*
+      The transition from single fragment document to a multi-fragment document
+      would cause a problem if the key and the first_key collide. In case of
+      a collision, old vector data could be served to HTTP. Need to avoid that.
+      Also, when evacuating a fragment, we have to decide if its the first_key
+      or the earliest_key based on the dir_tag.
+    */
+    do {
+      rand_CacheKey(&c->key, cont->mutex);
+    } while (DIR_MASK_TAG(c->key.slice32(2)) == DIR_MASK_TAG(c->first_key.slice32(2)));
+    c->earliest_key = c->key;
+  }
+
   c->frag_type = CACHE_FRAG_TYPE_HTTP;
   c->vol = key_to_vol(key, hostname, host_len);
   Vol *vol = c->vol;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ebd73715/proxy/hdrs/HTTP.cc
----------------------------------------------------------------------
diff --git a/proxy/hdrs/HTTP.cc b/proxy/hdrs/HTTP.cc
index a3b4cef..2108766 100644
--- a/proxy/hdrs/HTTP.cc
+++ b/proxy/hdrs/HTTP.cc
@@ -1782,7 +1782,7 @@ HTTPCacheAlt::HTTPCacheAlt():
   , m_ext_buffer(NULL)
 {
   m_flags = 0; // set all flags to false.
-  m_flag.writeable_p = true;
+  m_flag.writeable_p = true; // except this one.
 }
 
 void
@@ -1820,10 +1820,13 @@ HTTPCacheAlt::copy(HTTPCacheAlt *that)
 
   m_request_sent_time = that->m_request_sent_time;
   m_response_received_time = that->m_response_received_time;
+  m_fixed_fragment_size = that->m_fixed_fragment_size;
 
   m_frag_count = that->m_frag_count;
 
-  ats_free(m_fragments);
+  if (m_flag.table_allocated_p)
+    ats_free(m_fragments);
+
   if (that->m_fragments) {
     size_t size = FragmentDescriptorTable::calc_size(that->m_fragments->m_n);
     m_fragments = static_cast<FragmentDescriptorTable*>(ats_malloc(size));

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ebd73715/proxy/hdrs/HTTP.h
----------------------------------------------------------------------
diff --git a/proxy/hdrs/HTTP.h b/proxy/hdrs/HTTP.h
index 4aaf550..a42d686 100644
--- a/proxy/hdrs/HTTP.h
+++ b/proxy/hdrs/HTTP.h
@@ -1838,6 +1838,11 @@ public:
   {
     return m_alt->m_flag.complete_p;
   }
+  bool
+  is_writeable() const
+  {
+    return m_alt->m_flag.writeable_p;
+  }
 
   /** Compute the convex hull of uncached ranges.
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ebd73715/proxy/http/HttpSM.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 9826283..ab5d149 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -1540,7 +1540,8 @@ HttpSM::handle_api_return()
 
       setup_blind_tunnel(true);
     } else {
-      if (t_state.range_setup == HttpTransact::RANGE_PARTIAL_WRITE && HttpTransact::CACHE_DO_WRITE == t_state.cache_info.action) {
+      if ((t_state.range_setup == HttpTransact::RANGE_PARTIAL_WRITE || t_state.range_setup == HttpTransact::RANGE_PARTIAL_UPDATE) &&
+          HttpTransact::CACHE_DO_WRITE == t_state.cache_info.action) {
         Debug("amc", "Set up for partial read");
         CacheVConnection *save_write_vc = cache_sm.cache_write_vc;
         tunnel.tunnel_run(setup_server_transfer_to_cache_only());
@@ -5896,21 +5897,26 @@ void
 HttpSM::setup_cache_write_transfer(HttpCacheSM *c_sm, VConnection *source_vc, HTTPInfo *store_info, int64_t skip_bytes,
                                    const char *name)
 {
+  bool partial_update_p = HttpTransact::RANGE_PARTIAL_UPDATE == t_state.range_setup;
   ink_assert(c_sm->cache_write_vc != NULL);
   ink_assert(t_state.request_sent_time > 0);
   ink_assert(t_state.response_received_time > 0);
+  ink_assert(store_info->valid() || partial_update_p);
 
-  store_info->request_sent_time_set(t_state.request_sent_time);
-  store_info->response_received_time_set(t_state.response_received_time);
+  if (!partial_update_p) {
+    store_info->request_sent_time_set(t_state.request_sent_time);
+    store_info->response_received_time_set(t_state.response_received_time);
 
-  if (t_state.hdr_info.response_range.isValid()) {
-    if (t_state.hdr_info.response_content_size != HTTP_UNDEFINED_CL)
+    if (t_state.hdr_info.response_range.isValid() && t_state.hdr_info.response_content_size != HTTP_UNDEFINED_CL)
       store_info->object_size_set(t_state.hdr_info.response_content_size);
-    c_sm->cache_write_vc->set_inbound_range(t_state.hdr_info.response_range._min, t_state.hdr_info.response_range._max);
+
+    c_sm->cache_write_vc->set_http_info(store_info);
+    store_info->clear();
   }
 
-  c_sm->cache_write_vc->set_http_info(store_info);
-  store_info->clear();
+  if (t_state.hdr_info.response_range.isValid())
+    c_sm->cache_write_vc->set_inbound_range(t_state.hdr_info.response_range._min, t_state.hdr_info.response_range._max);
+
 
   tunnel.add_consumer(c_sm->cache_write_vc, source_vc, &HttpSM::tunnel_handler_cache_write, HT_CACHE_WRITE, name, skip_bytes);
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ebd73715/proxy/http/HttpTransact.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc
index e383ba9..7c71b11 100644
--- a/proxy/http/HttpTransact.cc
+++ b/proxy/http/HttpTransact.cc
@@ -2693,7 +2693,7 @@ HttpTransact::HandleCacheOpenReadHit(State *s)
 
   // Check if we need to get some data from the origin.
   if (s->state_machine->get_cache_sm().cache_read_vc->get_uncached(s->hdr_info.request_range, range)) {
-    Debug("amc", "Request has uncached fragments");
+    Debug("amc", "Request touches uncached fragments");
     find_server_and_update_current_info(s);
     if (!ats_is_ip(&s->current.server->addr)) {
       if (s->current.request_to == PARENT_PROXY) {
@@ -2707,7 +2707,7 @@ HttpTransact::HandleCacheOpenReadHit(State *s)
     }
     build_request(s, &s->hdr_info.client_request, &s->hdr_info.server_request, s->client_info.http_version, &range);
     s->cache_info.action = CACHE_PREPARE_TO_WRITE;
-    s->range_setup = RANGE_PARTIAL_WRITE;
+    s->range_setup = RANGE_PARTIAL_UPDATE;
     s->next_action = how_to_open_connection(s);
     if (s->stale_icp_lookup && s->next_action == SM_ACTION_ORIGIN_SERVER_OPEN) {
       s->next_action = SM_ACTION_ICP_QUERY;
@@ -4465,7 +4465,10 @@ HttpTransact::handle_cache_operation_on_forward_server_response(State *s)
   }
   ink_assert(base_response->valid());
 
-  if ((s->cache_info.action == CACHE_DO_WRITE) || (s->cache_info.action == CACHE_DO_REPLACE)) {
+  if (((s->cache_info.action == CACHE_DO_WRITE) || (s->cache_info.action == CACHE_DO_REPLACE)) &&
+      s->range_setup != RANGE_PARTIAL_UPDATE
+    ) {
+    // If it's a partial write then we already have the cached headers, no need to pass these in.
     set_headers_for_cache_write(s, &s->cache_info.object_store, &s->hdr_info.server_request, &s->hdr_info.server_response);
   }
   // 304, 412, and 416 responses are handled here

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ebd73715/proxy/http/HttpTransact.h
----------------------------------------------------------------------
diff --git a/proxy/http/HttpTransact.h b/proxy/http/HttpTransact.h
index 44d686c..de0c046 100644
--- a/proxy/http/HttpTransact.h
+++ b/proxy/http/HttpTransact.h
@@ -525,8 +525,8 @@ public:
   enum RangeSetup_t {
     RANGE_NONE = 0,
     RANGE_NOT_SATISFIABLE,
-    RANGE_PARTIAL_WRITE, // Do a partial write to the object.
-                         // Includes a partial request cache miss and a cache hit with uncached ranges
+    RANGE_PARTIAL_WRITE, ///< Cache a range request.
+    RANGE_PARTIAL_UPDATE, ///< Update an existing object with a range request.
   };
 
   enum CacheAuth_t {