Page Speed Optimization Libraries
1.6.29.3
|
00001 /* 00002 * Copyright 2011 Google Inc. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http:///www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00018 00019 #ifndef NET_INSTAWEB_REWRITER_PUBLIC_REWRITE_CONTEXT_H_ 00020 #define NET_INSTAWEB_REWRITER_PUBLIC_REWRITE_CONTEXT_H_ 00021 00022 #include <set> 00023 #include <vector> 00024 00025 #include "net/instaweb/http/public/http_cache.h" 00026 #include "net/instaweb/rewriter/cached_result.pb.h" 00027 #include "net/instaweb/rewriter/public/output_resource_kind.h" 00028 #include "net/instaweb/rewriter/public/resource.h" 00029 #include "net/instaweb/rewriter/public/server_context.h" 00030 #include "net/instaweb/rewriter/public/resource_slot.h" 00031 #include "net/instaweb/rewriter/public/rewrite_context.h" 00032 #include "net/instaweb/rewriter/public/rewrite_result.h" 00033 #include "net/instaweb/util/public/basictypes.h" 00034 #include "net/instaweb/util/public/scoped_ptr.h" 00035 #include "net/instaweb/util/public/string.h" 00036 #include "net/instaweb/util/public/string_util.h" 00037 #include "net/instaweb/util/public/url_segment_encoder.h" 00038 00039 namespace net_instaweb { 00040 00041 class AsyncFetch; 00042 class GoogleUrl; 00043 class MessageHandler; 00044 class NamedLock; 00045 class RequestTrace; 00046 class ResponseHeaders; 00047 class RewriteDriver; 00048 class RewriteOptions; 00049 class Statistics; 00050 class Variable; 00051 class Writer; 00052 00145 class RewriteContext { 00146 public: 00147 typedef std::vector<InputInfo*> InputInfoStarVector; 00148 static const char kNumDeadlineAlarmInvocations[]; 00149 static const char kNumDistributedRewriteSuccesses[]; 00150 static const char kNumDistributedRewriteFailures[]; 00151 static const char kNumDistributedMetadataFailures[]; 00153 static const char kDistributedExt[]; 00155 static const char kDistributedHash[]; 00156 00159 struct CacheLookupResult { 00160 CacheLookupResult() 00161 : cache_ok(false), 00162 can_revalidate(false), 00163 partitions(new OutputPartitions) {} 00164 00165 bool cache_ok; 00166 bool can_revalidate; 00167 InputInfoStarVector revalidate; 00168 scoped_ptr<OutputPartitions> partitions; 00169 }; 00170 00172 class CacheLookupResultCallback { 00173 public: 00174 CacheLookupResultCallback() {} 00175 virtual ~CacheLookupResultCallback(); 00176 virtual void Done(const GoogleString& cache_key, 00177 CacheLookupResult* result) = 0; 00178 private: 00179 DISALLOW_COPY_AND_ASSIGN(CacheLookupResultCallback); 00180 }; 00181 00184 RewriteContext(RewriteDriver* driver, 00185 RewriteContext* parent, 00186 ResourceContext* resource_context); 00187 virtual ~RewriteContext(); 00188 00193 int num_slots() const { return slots_.size(); } 00194 ResourceSlotPtr slot(int index) const { return slots_[index]; } 00195 00198 int num_outputs() const { return outputs_.size(); } 00199 OutputResourcePtr output(int i) const { return outputs_[i]; } 00200 00203 int num_output_partitions() const; 00204 const CachedResult* output_partition(int i) const; 00205 CachedResult* output_partition(int i); 00206 00209 bool chained() const { return chained_; } 00210 00214 void AddSlot(const ResourceSlotPtr& slot); 00215 00218 void RemoveLastSlot(); 00219 00225 void AddNestedContext(RewriteContext* context); 00226 00237 void Initiate(); 00238 00244 bool Fetch(const OutputResourcePtr& output_resource, 00245 AsyncFetch* fetch, 00246 MessageHandler* message_handler); 00247 00261 static bool LookupMetadataForOutputResource( 00262 const GoogleString& url, 00263 RewriteDriver* driver, 00264 GoogleString* error_out, 00265 CacheLookupResultCallback* callback); 00266 00269 bool slow() const { return slow_; } 00270 00272 bool is_metadata_cache_miss() const { return is_metadata_cache_miss_; } 00273 00275 bool has_parent() const { return parent_ != NULL; } 00276 00279 bool IsNestedIn(StringPiece id) const; 00280 00282 RewriteContext* parent() { return parent_; } 00283 const RewriteContext* parent() const { return parent_; } 00284 00286 void set_force_rewrite(bool x) { force_rewrite_ = x; } 00287 00288 bool rewrite_uncacheable() const { return rewrite_uncacheable_; } 00289 void set_rewrite_uncacheable(bool rewrite_uncacheable) { 00290 rewrite_uncacheable_ = rewrite_uncacheable; 00291 } 00292 00293 const ResourceContext* resource_context() const { 00294 return resource_context_.get(); 00295 } 00296 00298 GoogleString ToString(StringPiece prefix) const; 00299 00301 static void InitStats(Statistics* stats); 00302 00303 protected: 00304 typedef std::vector<GoogleUrl*> GoogleUrlStarVector; 00305 00310 00314 ServerContext* FindServerContext() const; 00315 const RewriteOptions* Options() const; 00316 RewriteDriver* Driver() const; 00317 00319 int num_nested() const { return nested_.size(); } 00320 RewriteContext* nested(int i) const { return nested_[i]; } 00321 00322 OutputPartitions* partitions() { return partitions_.get(); } 00323 00326 void AddRecheckDependency(); 00327 00331 virtual bool OptimizationOnly() const { return true; } 00332 00350 virtual bool Partition(OutputPartitions* partitions, 00351 OutputResourceVector* outputs); 00352 00358 virtual void PartitionAsync(OutputPartitions* partitions, 00359 OutputResourceVector* outputs); 00360 00364 void PartitionDone(bool result); 00365 00368 void CrossThreadPartitionDone(bool result); 00369 00388 virtual void Rewrite(int partition_index, 00389 CachedResult* partition, 00390 const OutputResourcePtr& output) = 0; 00391 00396 void RewriteDone(RewriteResult result, int partition_index); 00397 00404 virtual bool AbsolutifyIfNeeded(const StringPiece& input_contents, 00405 Writer* writer, MessageHandler* handler); 00406 00410 void StartNestedTasks(); 00411 00416 virtual void Harvest(); 00417 00429 virtual void Render(); 00430 00441 virtual void WillNotRender(); 00442 00446 virtual void Cancel(); 00447 00450 00457 virtual const UrlSegmentEncoder* encoder() const; 00458 00461 virtual GoogleString CacheKeySuffix() const; 00462 00469 virtual GoogleString UserAgentCacheKey( 00470 const ResourceContext* context) const { 00471 return ""; 00472 } 00473 00478 virtual void EncodeUserAgentIntoResourceContext(ResourceContext* context) {} 00479 00481 virtual const char* id() const = 0; 00482 00491 virtual OutputResourceKind kind() const = 0; 00492 00496 00499 void AttachDependentRequestTrace(const StringPiece& label); 00500 00504 RequestTrace* dependent_request_trace() { return dependent_request_trace_; } 00505 00508 void TracePrintf(const char* fmt, ...); 00509 00517 00527 virtual void StartFetchReconstruction(); 00528 00534 bool ShouldDistributeRewrite() const; 00535 00538 bool IsDistributedRewriteForHtml() const; 00539 00543 void DistributeRewrite(); 00544 00550 void DetachFetch(); 00551 00556 virtual bool DecodeFetchUrls(const OutputResourcePtr& output_resource, 00557 MessageHandler* message_handler, 00558 GoogleUrlStarVector* url_vector); 00559 00563 virtual void FixFetchFallbackHeaders(ResponseHeaders* headers); 00564 00567 virtual void FetchCallbackDone(bool success); 00568 00573 virtual void FetchTryFallback(const GoogleString& url, 00574 const StringPiece& hash); 00575 00577 void Freshen(); 00578 00579 bool notify_driver_on_fetch_done() const { 00580 return notify_driver_on_fetch_done_; 00581 } 00582 void set_notify_driver_on_fetch_done(bool value) { 00583 notify_driver_on_fetch_done_ = value; 00584 } 00585 00590 bool block_distribute_rewrite() const { return block_distribute_rewrite_; } 00591 void set_block_distribute_rewrite(const bool x) { 00592 block_distribute_rewrite_ = x; 00593 } 00594 00596 AsyncFetch* async_fetch(); 00597 00599 bool FetchContextDetached(); 00600 00602 MessageHandler* fetch_message_handler(); 00603 00605 bool stale_rewrite() const { return stale_rewrite_; } 00606 00610 virtual int64 GetRewriteDeadlineAlarmMs() const; 00611 00612 private: 00613 class DistributedRewriteCallback; 00614 class DistributedRewriteFetch; 00615 class OutputCacheCallback; 00616 class LookupMetadataForOutputResourceCallback; 00617 class HTTPCacheCallback; 00618 class ResourceCallbackUtils; 00619 class ResourceFetchCallback; 00620 class ResourceReconstructCallback; 00621 class ResourceRevalidateCallback; 00622 class InvokeRewriteFunction; 00623 class RewriteFreshenCallback; 00624 friend class RewriteDriver; 00625 00626 typedef std::set<RewriteContext*> ContextSet; 00627 00631 enum FallbackCondition { 00632 kFallbackDiscretional, 00633 00634 kFallbackEmergency 00635 00636 }; 00637 00639 void Start(); 00640 void SetPartitionKey(); 00641 void StartFetch(); 00642 void CancelFetch(); 00643 void OutputCacheDone(CacheLookupResult* cache_result); 00644 void OutputCacheHit(bool write_partitions); 00645 void OutputCacheRevalidate(const InputInfoStarVector& to_revalidate); 00646 void OutputCacheMiss(); 00647 void ResourceFetchDone(bool success, ResourcePtr resource, int slot_index); 00648 void ResourceRevalidateDone(InputInfo* input_info, bool success); 00649 void LogMetadataCacheInfo(bool cache_ok, bool can_revalidate); 00650 00655 void RepeatedSuccess(const RewriteContext* primary); 00656 void RepeatedFailure(); 00657 00666 void Finalize(); 00667 00669 NamedLock* Lock(); 00670 00680 void FetchInputs(); 00681 00686 void DistributeRewriteDone(bool success); 00687 00691 bool ParseAndRemoveMetadataFromResponseHeaders( 00692 ResponseHeaders* response_headers, CacheLookupResult* cache_result); 00693 00696 bool CreateOutputResourceFromContent(const CachedResult& cached_result, 00697 const ResponseHeaders& response_headers, 00698 StringPiece content, 00699 OutputResourcePtr* output_resource); 00700 00710 GoogleString DistributedFetchUrl(StringPiece url); 00711 00714 bool IsFetchRewrite() const { return fetch_.get() != NULL; } 00715 00720 void NestedRewriteDone(const RewriteContext* context); 00721 00725 void Activate(); 00726 00750 void Propagate(bool render_slots); 00751 00758 void StartRewriteForHtml(); 00759 void StartRewriteForFetch(); 00760 00767 bool ReadyToRewrite() const; 00768 00773 void DetachSlots(); 00774 00777 void RunSuccessors(); 00778 00781 void WritePartition(); 00782 00792 void FinalizeRewriteForHtml(); 00793 00799 void RetireRewriteForHtml(bool permit_render); 00800 00803 void MarkSlow(); 00804 00807 void MarkTooBusy(); 00808 00812 void CollectDependentTopLevel(ContextSet* contexts); 00813 00816 void RewriteDoneImpl(RewriteResult result, int partition_index); 00817 00820 void StartNestedTasksImpl(); 00821 00825 void RenderPartitionOnDetach(int partition_index); 00826 00829 bool PrepareFetch( 00830 const OutputResourcePtr& output_resource, 00831 AsyncFetch* fetch, 00832 MessageHandler* message_handler); 00833 00836 bool CreateOutputResourceForCachedOutput(const CachedResult* cached_result, 00837 OutputResourcePtr* output_resource); 00838 00840 void FetchCacheDone(CacheLookupResult* cache_result); 00841 00844 void FetchFallbackCacheDone(HTTPCache::FindResult result, 00845 HTTPCache::Callback* data); 00846 00851 bool CanFetchFallbackToOriginal(FallbackCondition circumstance) const; 00852 00854 ResourceSlotVector slots_; 00855 00859 std::vector<bool> render_slots_; 00860 00871 00872 bool started_; 00873 scoped_ptr<OutputPartitions> partitions_; 00874 OutputResourceVector outputs_; 00875 int outstanding_fetches_; 00876 int outstanding_rewrites_; 00877 scoped_ptr<ResourceContext> resource_context_; 00878 GoogleString partition_key_; 00879 00880 UrlSegmentEncoder default_encoder_; 00881 00884 scoped_ptr<NamedLock> lock_; 00885 00889 class FetchContext; 00890 scoped_ptr<FetchContext> fetch_; 00891 00894 std::vector<RewriteContext*> successors_; 00895 00899 std::vector<RewriteContext*> repeated_; 00900 00904 int num_pending_nested_; 00905 std::vector<RewriteContext*> nested_; 00906 00908 RewriteContext* parent_; 00909 00919 RewriteDriver* driver_; 00920 00922 int num_predecessors_; 00923 00926 bool chained_; 00927 00945 00947 bool rewrite_done_; 00948 00953 bool ok_to_write_output_partitions_; 00954 00957 bool was_too_busy_; 00958 00962 bool slow_; 00963 00965 bool revalidate_ok_; 00966 00969 bool notify_driver_on_fetch_done_; 00970 00973 bool force_rewrite_; 00974 00977 bool stale_rewrite_; 00978 00981 bool is_metadata_cache_miss_; 00982 00985 bool rewrite_uncacheable_; 00986 00989 RequestTrace* dependent_request_trace_; 00990 00993 bool block_distribute_rewrite_; 00994 00996 scoped_ptr<DistributedRewriteFetch> distributed_fetch_; 00997 00998 Variable* const num_distributed_rewrite_failures_; 00999 Variable* const num_distributed_rewrite_successes_; 01000 Variable* const num_distributed_metadata_failures_; 01001 DISALLOW_COPY_AND_ASSIGN(RewriteContext); 01002 }; 01003 01004 } 01005 01006 #endif ///< NET_INSTAWEB_REWRITER_PUBLIC_REWRITE_CONTEXT_H_