Page Speed Optimization Libraries
1.5.27.2
|
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 00093 class RewriteContext { 00094 public: 00095 typedef std::vector<InputInfo*> InputInfoStarVector; 00096 static const char kNumDeadlineAlarmInvocations[]; 00097 static const char kNumDistributedRewriteSuccesses[]; 00098 static const char kNumDistributedRewriteFailures[]; 00101 struct CacheLookupResult { 00102 CacheLookupResult() 00103 : cache_ok(false), 00104 can_revalidate(false), 00105 partitions(new OutputPartitions) {} 00106 00107 bool cache_ok; 00108 bool can_revalidate; 00109 InputInfoStarVector revalidate; 00110 scoped_ptr<OutputPartitions> partitions; 00111 }; 00112 00114 class CacheLookupResultCallback { 00115 public: 00116 CacheLookupResultCallback() {} 00117 virtual ~CacheLookupResultCallback(); 00118 virtual void Done(const GoogleString& cache_key, 00119 CacheLookupResult* result) = 0; 00120 private: 00121 DISALLOW_COPY_AND_ASSIGN(CacheLookupResultCallback); 00122 }; 00123 00126 RewriteContext(RewriteDriver* driver, 00127 RewriteContext* parent, 00128 ResourceContext* resource_context); 00129 virtual ~RewriteContext(); 00130 00135 int num_slots() const { return slots_.size(); } 00136 ResourceSlotPtr slot(int index) const { return slots_[index]; } 00137 00140 int num_outputs() const { return outputs_.size(); } 00141 OutputResourcePtr output(int i) const { return outputs_[i]; } 00142 00145 int num_output_partitions() const; 00146 const CachedResult* output_partition(int i) const; 00147 CachedResult* output_partition(int i); 00148 00151 bool chained() const { return chained_; } 00152 00156 void AddSlot(const ResourceSlotPtr& slot); 00157 00160 void RemoveLastSlot(); 00161 00172 void Initiate(); 00173 00181 bool Fetch(const OutputResourcePtr& output_resource, 00182 AsyncFetch* fetch, 00183 MessageHandler* message_handler); 00184 00198 static bool LookupMetadataForOutputResource( 00199 const GoogleString& url, 00200 RewriteDriver* driver, 00201 GoogleString* error_out, 00202 CacheLookupResultCallback* callback); 00203 00227 void Propagate(bool render_slots); 00228 00231 bool slow() const { return slow_; } 00232 00234 bool has_parent() const { return parent_ != NULL; } 00235 00237 RewriteContext* parent() { return parent_; } 00238 const RewriteContext* parent() const { return parent_; } 00239 00242 void AddNestedContext(RewriteContext* context); 00243 00245 void set_force_rewrite(bool x) { force_rewrite_ = x; } 00246 00251 bool block_distribute_rewrite() const { return block_distribute_rewrite_; } 00252 void set_block_distribute_rewrite(const bool x) { 00253 block_distribute_rewrite_ = x; 00254 } 00255 00256 const ResourceContext* resource_context() const { 00257 return resource_context_.get(); 00258 } 00259 00260 bool is_metadata_cache_miss() const { return is_metadata_cache_miss_; } 00261 00262 bool rewrite_uncacheable() const { return rewrite_uncacheable_; } 00263 void set_rewrite_uncacheable(bool rewrite_uncacheable) { 00264 rewrite_uncacheable_ = rewrite_uncacheable; 00265 } 00266 00271 void DetachSlots(); 00272 00274 GoogleString ToString(StringPiece prefix) const; 00275 00277 static void InitStats(Statistics* stats); 00278 00279 protected: 00280 typedef std::vector<GoogleUrl*> GoogleUrlStarVector; 00281 00284 void AttachDependentRequestTrace(const StringPiece& label); 00285 00289 RequestTrace* dependent_request_trace() { return dependent_request_trace_; } 00290 00293 void TracePrintf(const char* fmt, ...); 00294 00296 00300 ServerContext* FindServerContext() const; 00301 const RewriteOptions* Options() const; 00302 RewriteDriver* Driver() const; 00303 00306 void AddRecheckDependency(); 00307 00311 void RenderPartitionOnDetach(int partition_index); 00312 00317 void RewriteDone(RewriteResult result, int partition_index); 00318 00323 void NestedRewriteDone(const RewriteContext* context); 00324 00328 void StartNestedTasks(); 00329 00335 bool CreateOutputResourceForCachedOutput(const CachedResult* cached_result, 00336 bool force_hash_to_zero, 00337 OutputResourcePtr* output_resource); 00338 00342 virtual bool OptimizationOnly() const { return true; } 00343 00361 virtual bool Partition(OutputPartitions* partitions, 00362 OutputResourceVector* outputs); 00363 00369 virtual void PartitionAsync(OutputPartitions* partitions, 00370 OutputResourceVector* outputs); 00371 00375 void PartitionDone(bool result); 00376 00379 void CrossThreadPartitionDone(bool result); 00380 00392 virtual void Rewrite(int partition_index, 00393 CachedResult* partition, 00394 const OutputResourcePtr& output) = 0; 00395 00400 virtual void Harvest(); 00401 00413 virtual void Render(); 00414 00425 virtual void WillNotRender(); 00426 00430 virtual void Cancel(); 00431 00434 00441 virtual const UrlSegmentEncoder* encoder() const; 00442 00445 virtual GoogleString CacheKeySuffix() const; 00446 00448 virtual const char* id() const = 0; 00449 00458 virtual OutputResourceKind kind() const = 0; 00459 00469 virtual void StartFetchReconstruction(); 00470 00475 bool ShouldDistributeRewrite() const; 00476 00478 void DistributeRewrite(); 00479 00485 void DetachFetch(); 00486 00491 virtual bool DecodeFetchUrls(const OutputResourcePtr& output_resource, 00492 MessageHandler* message_handler, 00493 GoogleUrlStarVector* url_vector); 00494 00498 virtual void FixFetchFallbackHeaders(ResponseHeaders* headers); 00499 00502 virtual void FetchCallbackDone(bool success); 00503 00510 virtual bool AbsolutifyIfNeeded(const StringPiece& input_contents, 00511 Writer* writer, MessageHandler* handler); 00512 00517 virtual void FetchTryFallback(const GoogleString& url, 00518 const StringPiece& hash); 00519 00521 void Freshen(); 00522 00524 int num_nested() const { return nested_.size(); } 00525 RewriteContext* nested(int i) const { return nested_[i]; } 00526 00527 OutputPartitions* partitions() { return partitions_.get(); } 00528 00529 void set_notify_driver_on_fetch_done(bool value) { 00530 notify_driver_on_fetch_done_ = value; 00531 } 00532 00534 AsyncFetch* async_fetch(); 00535 00537 bool FetchContextDetached(); 00538 00540 MessageHandler* fetch_message_handler(); 00541 00543 bool stale_rewrite() const { return stale_rewrite_; } 00544 00548 virtual int64 GetRewriteDeadlineAlarmMs() const; 00549 00555 virtual GoogleString UserAgentCacheKey( 00556 const ResourceContext* context) const { 00557 return ""; 00558 } 00559 00564 virtual void EncodeUserAgentIntoResourceContext(ResourceContext* context) {} 00565 00566 private: 00567 class DistributedRewriteCallback; 00568 class DistributedRewriteFetch; 00569 class OutputCacheCallback; 00570 class LookupMetadataForOutputResourceCallback; 00571 class HTTPCacheCallback; 00572 class ResourceCallbackUtils; 00573 class ResourceFetchCallback; 00574 class ResourceReconstructCallback; 00575 class ResourceRevalidateCallback; 00576 class InvokeRewriteFunction; 00577 class RewriteFreshenCallback; 00578 friend class RewriteDriver; 00579 00580 typedef std::set<RewriteContext*> ContextSet; 00581 00585 enum FallbackCondition { 00586 kFallbackDiscretional, 00587 00588 kFallbackEmergency 00589 00590 }; 00591 00593 void Start(); 00594 void SetPartitionKey(); 00595 void StartFetch(); 00596 void CancelFetch(); 00597 void OutputCacheDone(CacheLookupResult* cache_result); 00598 void OutputCacheHit(bool write_partitions); 00599 void OutputCacheRevalidate(const InputInfoStarVector& to_revalidate); 00600 void OutputCacheMiss(); 00601 void ResourceFetchDone(bool success, ResourcePtr resource, int slot_index); 00602 void ResourceRevalidateDone(InputInfo* input_info, bool success); 00603 void LogMetadataCacheInfo(bool cache_ok, bool can_revalidate); 00604 00609 void RepeatedSuccess(const RewriteContext* primary); 00610 void RepeatedFailure(); 00611 00620 void Finalize(); 00621 00623 NamedLock* Lock(); 00624 00634 void FetchInputs(); 00635 00640 void DistributeRewriteDone(bool success); 00641 00645 void Activate(); 00646 00653 void StartRewriteForHtml(); 00654 void StartRewriteForFetch(); 00655 00662 bool ReadyToRewrite() const; 00663 00666 void RunSuccessors(); 00667 00670 void WritePartition(); 00671 00681 void FinalizeRewriteForHtml(); 00682 00688 void RetireRewriteForHtml(bool permit_render); 00689 00692 void MarkSlow(); 00693 00696 void MarkTooBusy(); 00697 00701 void CollectDependentTopLevel(ContextSet* contexts); 00702 00705 void RewriteDoneImpl(RewriteResult result, int partition_index); 00706 00709 void StartNestedTasksImpl(); 00710 00713 bool PrepareFetch( 00714 const OutputResourcePtr& output_resource, 00715 AsyncFetch* fetch, 00716 MessageHandler* message_handler); 00717 00719 void FetchCacheDone(CacheLookupResult* cache_result); 00720 00723 void FetchFallbackCacheDone(HTTPCache::FindResult result, 00724 HTTPCache::Callback* data); 00725 00730 bool CanFetchFallbackToOriginal(FallbackCondition circumstance) const; 00731 00734 virtual bool do_stale_rewrite() const { return true; } 00735 00737 ResourceSlotVector slots_; 00738 00742 std::vector<bool> render_slots_; 00743 00754 00755 bool started_; 00756 scoped_ptr<OutputPartitions> partitions_; 00757 OutputResourceVector outputs_; 00758 int outstanding_fetches_; 00759 int outstanding_rewrites_; 00760 scoped_ptr<ResourceContext> resource_context_; 00761 GoogleString partition_key_; 00762 00763 UrlSegmentEncoder default_encoder_; 00764 00767 scoped_ptr<NamedLock> lock_; 00768 00772 class FetchContext; 00773 scoped_ptr<FetchContext> fetch_; 00774 00777 std::vector<RewriteContext*> successors_; 00778 00782 std::vector<RewriteContext*> repeated_; 00783 00787 int num_pending_nested_; 00788 std::vector<RewriteContext*> nested_; 00789 00791 RewriteContext* parent_; 00792 00802 RewriteDriver* driver_; 00803 00805 int num_predecessors_; 00806 00809 bool chained_; 00810 00828 00830 bool rewrite_done_; 00831 00836 bool ok_to_write_output_partitions_; 00837 00840 bool was_too_busy_; 00841 00845 bool slow_; 00846 00848 bool revalidate_ok_; 00849 00852 bool notify_driver_on_fetch_done_; 00853 00856 bool force_rewrite_; 00857 00860 bool stale_rewrite_; 00861 00864 bool is_metadata_cache_miss_; 00865 00868 bool rewrite_uncacheable_; 00869 00872 RequestTrace* dependent_request_trace_; 00873 00876 bool block_distribute_rewrite_; 00877 00879 scoped_ptr<DistributedRewriteFetch> distributed_fetch_; 00880 00881 Variable* const num_distributed_rewrite_failures_; 00882 Variable* const num_distributed_rewrite_successes_; 00883 00884 DISALLOW_COPY_AND_ASSIGN(RewriteContext); 00885 }; 00886 00887 } 00888 00889 #endif ///< NET_INSTAWEB_REWRITER_PUBLIC_REWRITE_CONTEXT_H_