Repository: trafficserver Updated Branches: refs/heads/ts-974-5-3-x ebd737154 -> bf93bbb84
Fixed second full read problem. Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/bf93bbb8 Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/bf93bbb8 Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/bf93bbb8 Branch: refs/heads/ts-974-5-3-x Commit: bf93bbb84a2c462c9249fdff8cfdd93b8a4f75ea Parents: ebd7371 Author: Alan M. Carroll <[email protected]> Authored: Mon Jun 8 09:28:34 2015 -0500 Committer: Alan M. Carroll <[email protected]> Committed: Mon Jun 8 09:28:34 2015 -0500 ---------------------------------------------------------------------- iocore/cache/Cache.cc | 6 +++--- iocore/cache/CacheHttp.cc | 11 +++++++---- iocore/cache/I_Cache.h | 8 +++++++- iocore/cache/P_CacheHttp.h | 2 +- iocore/cache/P_CacheInternal.h | 2 +- proxy/hdrs/HTTP.cc | 14 +++++++++----- proxy/hdrs/HTTP.h | 7 +++++-- proxy/http/HttpTransact.cc | 7 ++++++- proxy/http/HttpTransactHeaders.cc | 2 +- 9 files changed, 40 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/bf93bbb8/iocore/cache/Cache.cc ---------------------------------------------------------------------- diff --git a/iocore/cache/Cache.cc b/iocore/cache/Cache.cc index 478e732..6095ddb 100644 --- a/iocore/cache/Cache.cc +++ b/iocore/cache/Cache.cc @@ -516,10 +516,10 @@ CacheVC::set_content_range(HTTPRangeSpec const& r) } bool -CacheVC::get_uncached(HTTPRangeSpec const& req, HTTPRangeSpec& result) +CacheVC::get_uncached(HTTPRangeSpec const& req, HTTPRangeSpec& result, int64_t initial) { - HTTPRangeSpec::Range r = od ? write_vector->get_uncached_hull(earliest_key, req) - : alternate.get_uncached_hull(req) + HTTPRangeSpec::Range r = od ? write_vector->get_uncached_hull(earliest_key, req, initial) + : alternate.get_uncached_hull(req, initial) ; if (r.isValid()) { result.add(r); http://git-wip-us.apache.org/repos/asf/trafficserver/blob/bf93bbb8/iocore/cache/CacheHttp.cc ---------------------------------------------------------------------- diff --git a/iocore/cache/CacheHttp.cc b/iocore/cache/CacheHttp.cc index 623e5b8..dd4b4fc 100644 --- a/iocore/cache/CacheHttp.cc +++ b/iocore/cache/CacheHttp.cc @@ -355,7 +355,7 @@ CacheHTTPInfoVector::close_writer(CacheKey const& alt_key, CacheVC* vc) -------------------------------------------------------------------------*/ HTTPRangeSpec::Range -CacheHTTPInfoVector::get_uncached_hull(CacheKey const& alt_key, HTTPRangeSpec const& req) +CacheHTTPInfoVector::get_uncached_hull(CacheKey const& alt_key, HTTPRangeSpec const& req, int64_t initial) { int alt_idx = this->index_of(alt_key); Item& item = data[alt_idx]; @@ -364,7 +364,7 @@ CacheHTTPInfoVector::get_uncached_hull(CacheKey const& alt_key, HTTPRangeSpec co CacheVC* cycle_vc = NULL; // Yeah, this need to be tunable. uint64_t DELTA = item._alternate.get_frag_fixed_size() * 16; - HTTPRangeSpec::Range r(item._alternate.get_uncached_hull(req)); + HTTPRangeSpec::Range r(item._alternate.get_uncached_hull(req, initial)); if (r.isValid()) { /* Now clip against the writers. @@ -424,12 +424,15 @@ CacheRange::init(HTTPHdr* req) bool CacheRange::start() { - bool zret = false; + bool zret = true; if (_r.hasRanges()) { _offset = _r[_idx = 0]._min; _pending_range_shift_p = _r.isMulti(); - zret = true; + } else if (_r.isEmpty()) { + _offset = 0; + } else { + zret = false; } return zret; } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/bf93bbb8/iocore/cache/I_Cache.h ---------------------------------------------------------------------- diff --git a/iocore/cache/I_Cache.h b/iocore/cache/I_Cache.h index 187343b..675ee82 100644 --- a/iocore/cache/I_Cache.h +++ b/iocore/cache/I_Cache.h @@ -254,7 +254,13 @@ struct CacheVConnection : public VConnection { /// @return @c true if the @a result is not empty. /// @internal Currently this just returns the single range that is convex hull of the uncached request. /// Someday we may want to do the exact range spec but we use the type for now because it's easier. - virtual bool get_uncached(HTTPRangeSpec const& req, HTTPRangeSpec& result) { (void)req; (void)result; return false; } + virtual bool get_uncached(HTTPRangeSpec const& req, HTTPRangeSpec& result, int64_t initial) + { + (void)req; + (void)result; + (void)initial; + return false; + } /** Set the range for the input (response content). The incoming bytes will be written to this section of the object. http://git-wip-us.apache.org/repos/asf/trafficserver/blob/bf93bbb8/iocore/cache/P_CacheHttp.h ---------------------------------------------------------------------- diff --git a/iocore/cache/P_CacheHttp.h b/iocore/cache/P_CacheHttp.h index 458fb9e..ea0ac43 100644 --- a/iocore/cache/P_CacheHttp.h +++ b/iocore/cache/P_CacheHttp.h @@ -148,7 +148,7 @@ struct CacheHTTPInfoVector { @return @c true if there is uncached data that must be retrieved. */ - HTTPRangeSpec::Range get_uncached_hull(CacheKey const &alt_key, HTTPRangeSpec const &request); + HTTPRangeSpec::Range get_uncached_hull(CacheKey const &alt_key, HTTPRangeSpec const &request, int64_t initial); /** Sigh, yet another custom array class. @c Vec doesn't work because it really only works well with pointers, not objects. http://git-wip-us.apache.org/repos/asf/trafficserver/blob/bf93bbb8/iocore/cache/P_CacheInternal.h ---------------------------------------------------------------------- diff --git a/iocore/cache/P_CacheInternal.h b/iocore/cache/P_CacheInternal.h index 0aca4f2..5de9158 100644 --- a/iocore/cache/P_CacheInternal.h +++ b/iocore/cache/P_CacheInternal.h @@ -392,7 +392,7 @@ struct CacheVC: public CacheVConnection virtual char const* get_http_range_boundary_string(int* len) const; virtual int64_t get_effective_content_size(); virtual void set_full_content_length(int64_t size); - virtual bool get_uncached(HTTPRangeSpec const& req, HTTPRangeSpec& result); + virtual bool get_uncached(HTTPRangeSpec const& req, HTTPRangeSpec& result, int64_t initial); /** This sets a range for data flowing in to the cache VC. The CacheVC will write the incoming data to this part of the overall object. @internal It's done this way to isolate the CacheVC from parsing range separators http://git-wip-us.apache.org/repos/asf/trafficserver/blob/bf93bbb8/proxy/hdrs/HTTP.cc ---------------------------------------------------------------------- diff --git a/proxy/hdrs/HTTP.cc b/proxy/hdrs/HTTP.cc index 2108766..ace4185 100644 --- a/proxy/hdrs/HTTP.cc +++ b/proxy/hdrs/HTTP.cc @@ -1827,6 +1827,9 @@ HTTPCacheAlt::copy(HTTPCacheAlt *that) if (m_flag.table_allocated_p) ats_free(m_fragments); + // Safe to copy now, and we need to do that before we copy the fragment table. + m_flags = that->m_flags; + if (that->m_fragments) { size_t size = FragmentDescriptorTable::calc_size(that->m_fragments->m_n); m_fragments = static_cast<FragmentDescriptorTable*>(ats_malloc(size)); @@ -1834,6 +1837,7 @@ HTTPCacheAlt::copy(HTTPCacheAlt *that) m_flag.table_allocated_p = true; } else { m_fragments = 0; + m_flag.table_allocated_p = false; } } @@ -2189,7 +2193,7 @@ HTTPInfo::mark_frag_write(unsigned int idx) { while (j < m_alt->m_frag_count && (*m_alt->m_fragments)[j].m_flag.cached_p) ++j; m_alt->m_fragments->m_cached_idx = j - 1; - if (m_alt->m_flag.content_length_p && + if (!m_alt->m_flag.content_length_p && (this->get_frag_fixed_size() + this->get_frag_offset(j-1)) > static_cast<int64_t>(m_alt->m_earliest.m_offset)) m_alt->m_flag.complete_p = true; } @@ -2563,10 +2567,10 @@ HTTPRangeSpec::print(char* buff, size_t len) const } int -HTTPRangeSpec::print_quantized(char* buff, size_t len, int64_t quantum, int64_t interstitial, int64_t initial) const +HTTPRangeSpec::print_quantized(char* buff, size_t len, int64_t quantum, int64_t interstitial) const { static const int MAX_R = 20; // this needs to be promoted - // We will want a max # of ranges, probably a build time constant, in the not so distant + // We will want to have a max # of ranges limit, probably a build time constant, in the not so distant // future anyway, so might as well start here. int qrn = 0; // count of quantized ranges Range qr[MAX_R]; // quantized ranges @@ -2585,7 +2589,6 @@ HTTPRangeSpec::print_quantized(char* buff, size_t len, int64_t quantum, int64_t r._min = (r._min / quantum) * quantum; r._max = ((r._max + quantum - 1)/quantum) * quantum - 1; } - if (1 < initial && r._min < static_cast<uint64_t>(initial)) r._min = 0; // blend in to the current ranges for ( i = 0 ; i < qrn ; ++i ) { Range& cr = qr[i]; @@ -2634,7 +2637,7 @@ HTTPInfo::get_range_for_frags(int low, int high) */ HTTPRangeSpec::Range -HTTPInfo::get_uncached_hull(HTTPRangeSpec const& req) +HTTPInfo::get_uncached_hull(HTTPRangeSpec const& req, int64_t initial) { HTTPRangeSpec::Range r; @@ -2673,6 +2676,7 @@ HTTPInfo::get_uncached_hull(HTTPRangeSpec const& req) } if (r.isValid() && m_alt->m_flag.content_length_p && static_cast<int64_t>(r._max) > this->object_size_get()) r._max = this->object_size_get(); + if (static_cast<int64_t>(r._min) < initial && !m_alt->m_earliest.m_flag.cached_p) r._min = 0; } return r; } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/bf93bbb8/proxy/hdrs/HTTP.h ---------------------------------------------------------------------- diff --git a/proxy/hdrs/HTTP.h b/proxy/hdrs/HTTP.h index a42d686..b7b3ab0 100644 --- a/proxy/hdrs/HTTP.h +++ b/proxy/hdrs/HTTP.h @@ -609,8 +609,6 @@ struct HTTPRangeSpec { int64_t quantum ///< Align ranges to multiples of this value. , int64_t interstitial ///< Require gaps to be at least this large. - , - int64_t initial ///< Require the initial gap to be at least this large. ) const; /// Print the @a ranges. @@ -1846,9 +1844,14 @@ public: /** Compute the convex hull of uncached ranges. + If the resulting range has a minimum that is less than @a initial @b and the earliest fragment + is not cached then the minimum will be changed to zero. Alternatively, the initial uncached + segment must be at least @a initial bytes long. + @return An invalid range if all of the request is available in cache. */ HTTPRangeSpec::Range get_uncached_hull(HTTPRangeSpec const &req ///< [in] UA request with content length applied + , int64_t initial ///< Minimize size for uncached initial data ); /// Get the fragment table. http://git-wip-us.apache.org/repos/asf/trafficserver/blob/bf93bbb8/proxy/http/HttpTransact.cc ---------------------------------------------------------------------- diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc index 7c71b11..6fcba7b 100644 --- a/proxy/http/HttpTransact.cc +++ b/proxy/http/HttpTransact.cc @@ -49,6 +49,11 @@ static char const HTTP_RANGE_MULTIPART_CONTENT_TYPE[] = "multipart/byteranges; boundary="; +/// If the intial uncached segment is less than this, expand the request to include the earliest fragment. +/// Hardwired for now, this needs to be promoted to a config var at some point. It should also be a multiple +/// of the fragment size. +static int64_t const MIN_INITIAL_UNCACHED = 4 * 1<<20; + #define HTTP_INCREMENT_TRANS_STAT(X) update_stat(s, X, 1); #define HTTP_SUM_TRANS_STAT(X, S) update_stat(s, X, (ink_statval_t)S); @@ -2692,7 +2697,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)) { + if (s->state_machine->get_cache_sm().cache_read_vc->get_uncached(s->hdr_info.request_range, range, MIN_INITIAL_UNCACHED)) { Debug("amc", "Request touches uncached fragments"); find_server_and_update_current_info(s); if (!ats_is_ip(&s->current.server->addr)) { http://git-wip-us.apache.org/repos/asf/trafficserver/blob/bf93bbb8/proxy/http/HttpTransactHeaders.cc ---------------------------------------------------------------------- diff --git a/proxy/http/HttpTransactHeaders.cc b/proxy/http/HttpTransactHeaders.cc index a5277bb..7c41850 100644 --- a/proxy/http/HttpTransactHeaders.cc +++ b/proxy/http/HttpTransactHeaders.cc @@ -1045,7 +1045,7 @@ HttpTransactHeaders::insert_request_range_header(HTTPHdr* header, HTTPRangeSpec if (ranges->hasRanges()) { int64_t ffs = cacheProcessor.get_fixed_fragment_size(); - n = ranges->print_quantized(buff, sizeof(buff), ffs, ffs, 4 * ffs); + n = ranges->print_quantized(buff, sizeof(buff), ffs, ffs); header->value_set(MIME_FIELD_RANGE, MIME_LEN_RANGE, buff, n); } }
