You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by su...@apache.org on 2014/09/23 01:46:18 UTC
git commit: [TS-2314] - New config to allow unsatifiable Range:
request to go straight to Origin
Repository: trafficserver
Updated Branches:
refs/heads/master 2b64392d8 -> 15d3887b0
[TS-2314] - New config to allow unsatifiable Range: request to go straight to Origin
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/15d3887b
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/15d3887b
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/15d3887b
Branch: refs/heads/master
Commit: 15d3887b03a3f8e70436cd995a3ada0963a77423
Parents: 2b64392
Author: Sudheer Vinukonda <su...@yahoo-inc.com>
Authored: Mon Sep 22 23:45:42 2014 +0000
Committer: Sudheer Vinukonda <su...@yahoo-inc.com>
Committed: Mon Sep 22 23:45:42 2014 +0000
----------------------------------------------------------------------
.../configuration/records.config.en.rst | 17 ++++-
proxy/http/HttpSM.cc | 70 ++++++++++++++------
proxy/http/HttpSM.h | 1 +
proxy/http/HttpTransact.cc | 4 +-
proxy/http/HttpTransact.h | 4 +-
5 files changed, 71 insertions(+), 25 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/15d3887b/doc/reference/configuration/records.config.en.rst
----------------------------------------------------------------------
diff --git a/doc/reference/configuration/records.config.en.rst b/doc/reference/configuration/records.config.en.rst
index cec4de6..defcefe 100644
--- a/doc/reference/configuration/records.config.en.rst
+++ b/doc/reference/configuration/records.config.en.rst
@@ -1086,8 +1086,21 @@ Cache Control
.. ts:cv:: CONFIG proxy.config.cache.enable_read_while_writer INT 1
:reloadable:
- Enables (``1``) or disables (``0``) ability to a read cached object while the another connection is completing the write to cache for
- the same object. Several other configuration values need to be set for this to become active. See :ref:`reducing-origin-server-requests-avoiding-the-thundering-herd`
+ Specifies when to enable the ability to read a cached object while another
+ connection is completing the write to cache for that same object. The goal
+ here is to avoid multiple origin connections for the same cacheable object
+ upon a cache miss. The possible values of this config are:
+
+ - ``0`` = never allow
+ - ``1`` = always allowed
+ - ``2`` = allowed, only if the ``Range`` requested can be satisfied from cache
+
+ The ``2`` option is useful to avoid delaying requests which can not easily
+ be satisfied by the partially written response.
+
+ Several other configuration values need to be set for this to be
+ usable. See :ref:`Reducing Origin Server Requests
+ <http-proxy-caching.en.html#reducing-origin-server-requests-avoiding-the-thundering-herd>`.
.. ts:cv:: CONFIG proxy.config.cache.force_sector_size INT 0
:reloadable:
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/15d3887b/proxy/http/HttpSM.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 166cb7e..7d44149 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -327,7 +327,8 @@ HttpSM::HttpSM()
pushed_response_hdr_bytes(0), pushed_response_body_bytes(0),
plugin_tag(0), plugin_id(0),
hooks_set(false), cur_hook_id(TS_HTTP_LAST_HOOK), cur_hook(NULL),
- cur_hooks(0), callout_state(HTTP_API_NO_CALLOUT), terminate_sm(false), kill_this_async_done(false)
+ cur_hooks(0), callout_state(HTTP_API_NO_CALLOUT), terminate_sm(false),
+ kill_this_async_done(false), parse_range_done(false)
{
static int scatter_init = 0;
@@ -4114,6 +4115,12 @@ HttpSM::parse_range_and_compare(MIMEField *field, int64_t content_length)
return;
}
+ if (parse_range_done) {
+ Debug("http_range", "parse_range already done, t_state.range_setup %d", t_state.range_setup);
+ return;
+ }
+ parse_range_done = true;
+
n_values = 0;
value = csv.get_first(field, &value_len);
while (value) {
@@ -4129,6 +4136,9 @@ HttpSM::parse_range_and_compare(MIMEField *field, int64_t content_length)
value += 6; // skip leading 'bytes='
value_len -= 6;
+ // assume range_in_cache
+ t_state.range_in_cache = true;
+
for (; value; value = csv.get_next(&value_len)) {
if (!(tmp = (const char *) memchr(value, '-', value_len))) {
t_state.range_setup = HttpTransact::RANGE_NONE;
@@ -4211,6 +4221,17 @@ HttpSM::parse_range_and_compare(MIMEField *field, int64_t content_length)
ranges[nr]._start = start;
ranges[nr]._end = end;
++nr;
+
+ if (!cache_sm.cache_read_vc->is_pread_capable() && cache_config_read_while_writer==2) {
+ // write in progress, check if request range not in cache yet
+ HTTPInfo::FragOffset* frag_offset_tbl = t_state.cache_info.object_read->get_frag_table();
+ int frag_offset_cnt = t_state.cache_info.object_read->get_frag_offset_count();
+
+ if (!frag_offset_tbl || (frag_offset_tbl[frag_offset_cnt - 1] < end)) {
+ Debug("http_range", "request range in cache, end %" PRId64 ", frg_offset_cnt %d, frag_size %" PRId64, end, frag_offset_cnt, frag_offset_tbl[frag_offset_cnt - 1]);
+ t_state.range_in_cache = false;
+ }
+ }
}
if (nr > 0) {
@@ -4224,6 +4245,7 @@ HttpSM::parse_range_and_compare(MIMEField *field, int64_t content_length)
t_state.range_setup = HttpTransact::RANGE_NOT_SATISFIABLE;
Lfaild:
+ t_state.range_in_cache = false;
t_state.num_range_fields = -1;
delete []ranges;
return;
@@ -4295,26 +4317,32 @@ HttpSM::do_range_setup_if_necessary()
if (t_state.method == HTTP_WKSIDX_GET && t_state.hdr_info.client_request.version_get() == HTTPVersion(1, 1)) {
do_range_parse(field);
- // if only one range entry and pread is capable, no need transform range
- if (t_state.range_setup == HttpTransact::RANGE_REQUESTED &&
- t_state.num_range_fields == 1 &&
- cache_sm.cache_read_vc->is_pread_capable())
- t_state.range_setup = HttpTransact::RANGE_NOT_TRANSFORM_REQUESTED;
-
- if (t_state.range_setup == HttpTransact::RANGE_REQUESTED &&
- api_hooks.get(TS_HTTP_RESPONSE_TRANSFORM_HOOK) == NULL) {
- Debug("http_trans", "Unable to accelerate range request, fallback to transform");
- content_type = t_state.cache_info.object_read->response_get()->value_get(MIME_FIELD_CONTENT_TYPE, MIME_LEN_CONTENT_TYPE, &field_content_type_len);
- //create a Range: transform processor for requests of type Range: bytes=1-2,4-5,10-100 (eg. multiple ranges)
- range_trans = transformProcessor.range_transform(mutex,
- t_state.ranges,
- t_state.num_range_fields,
- &t_state.hdr_info.transform_response,
- content_type,
- field_content_type_len,
- t_state.cache_info.object_read->object_size_get()
- );
- api_hooks.append(TS_HTTP_RESPONSE_TRANSFORM_HOOK, range_trans);
+ if (t_state.range_setup == HttpTransact::RANGE_REQUESTED) {
+
+ if (!t_state.range_in_cache) {
+ Debug("http_range", "range can't be satisifed from cache, force origin request");
+ t_state.cache_lookup_result = HttpTransact::CACHE_LOOKUP_MISS;
+ return;
+ }
+
+ // if only one range entry and pread is capable, no need transform range
+ if (t_state.num_range_fields == 1 &&
+ (cache_sm.cache_read_vc->is_pread_capable() || t_state.range_in_cache)) {
+ t_state.range_setup = HttpTransact::RANGE_NOT_TRANSFORM_REQUESTED;
+ } else if (api_hooks.get(TS_HTTP_RESPONSE_TRANSFORM_HOOK) == NULL) {
+ Debug("http_trans", "Unable to accelerate range request, fallback to transform");
+ content_type = t_state.cache_info.object_read->response_get()->value_get(MIME_FIELD_CONTENT_TYPE, MIME_LEN_CONTENT_TYPE, &field_content_type_len);
+ //create a Range: transform processor for requests of type Range: bytes=1-2,4-5,10-100 (eg. multiple ranges)
+ range_trans = transformProcessor.range_transform(mutex,
+ t_state.ranges,
+ t_state.num_range_fields,
+ &t_state.hdr_info.transform_response,
+ content_type,
+ field_content_type_len,
+ t_state.cache_info.object_read->object_size_get()
+ );
+ api_hooks.append(TS_HTTP_RESPONSE_TRANSFORM_HOOK, range_trans);
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/15d3887b/proxy/http/HttpSM.h
----------------------------------------------------------------------
diff --git a/proxy/http/HttpSM.h b/proxy/http/HttpSM.h
index 015a59b..e143ab8 100644
--- a/proxy/http/HttpSM.h
+++ b/proxy/http/HttpSM.h
@@ -520,6 +520,7 @@ protected:
// when the flag is set
bool terminate_sm;
bool kill_this_async_done;
+ bool parse_range_done;
virtual int kill_this_async_hook(int event, void *data);
void kill_this();
void update_stats();
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/15d3887b/proxy/http/HttpTransact.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc
index 568b2d3..293a168 100644
--- a/proxy/http/HttpTransact.cc
+++ b/proxy/http/HttpTransact.cc
@@ -67,6 +67,7 @@ static char range_type[] = "multipart/byteranges; boundary=RANGE_SEPARATOR";
extern HttpBodyFactory *body_factory;
extern int cache_config_vary_on_user_agent;
+extern int cache_config_read_while_writer;
static const char local_host_ip_str[] = "127.0.0.1";
@@ -2863,8 +2864,9 @@ HttpTransact::build_response_from_cache(State* s, HTTPWarningCode warning_code)
s->cache_info.action = CACHE_DO_NO_ACTION;
s->next_action = SM_ACTION_INTERNAL_CACHE_NOOP;
break;
- } else if (s->range_setup == RANGE_NOT_HANDLED) {
+ } else if ((s->range_setup == RANGE_NOT_HANDLED) || !s->range_in_cache) {
// we switch to tunneling for Range requests if it is out of order.
+ // or if the range can't be satisfied from the cache
// In that case we fetch the entire source so it's OK to switch
// this late.
DebugTxn("http_seq", "[HttpTransact::HandleCacheOpenReadHit] Out-of-order Range request - tunneling");
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/15d3887b/proxy/http/HttpTransact.h
----------------------------------------------------------------------
diff --git a/proxy/http/HttpTransact.h b/proxy/http/HttpTransact.h
index 59b76ef..f35d0fe 100644
--- a/proxy/http/HttpTransact.h
+++ b/proxy/http/HttpTransact.h
@@ -1017,6 +1017,7 @@ public:
OverridableHttpConfigParams my_txn_conf; // Storage for plugins, to avoid malloc
bool transparent_passthrough;
+ bool range_in_cache;
// Methods
void
@@ -1112,7 +1113,8 @@ public:
range_output_cl(0),
ranges(NULL),
txn_conf(NULL),
- transparent_passthrough(false)
+ transparent_passthrough(false),
+ range_in_cache(false)
{
int i;
char *via_ptr = via_string;