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 {