Page Speed Optimization Libraries
1.3.25.1
|
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 Writer; 00051 00092 class RewriteContext { 00093 public: 00094 typedef std::vector<InputInfo*> InputInfoStarVector; 00095 static const char kNumDeadlineAlarmInvocations[]; 00098 struct CacheLookupResult { 00099 CacheLookupResult() 00100 : cache_ok(false), 00101 can_revalidate(false), 00102 partitions(new OutputPartitions) {} 00103 00104 bool cache_ok; 00105 bool can_revalidate; 00106 InputInfoStarVector revalidate; 00107 scoped_ptr<OutputPartitions> partitions; 00108 }; 00109 00111 class CacheLookupResultCallback { 00112 public: 00113 CacheLookupResultCallback() {} 00114 virtual ~CacheLookupResultCallback(); 00115 virtual void Done(const GoogleString& cache_key, 00116 CacheLookupResult* result) = 0; 00117 private: 00118 DISALLOW_COPY_AND_ASSIGN(CacheLookupResultCallback); 00119 }; 00120 00123 RewriteContext(RewriteDriver* driver, 00124 RewriteContext* parent, 00125 ResourceContext* resource_context); 00126 virtual ~RewriteContext(); 00127 00132 int num_slots() const { return slots_.size(); } 00133 ResourceSlotPtr slot(int index) const { return slots_[index]; } 00134 00137 int num_outputs() const { return outputs_.size(); } 00138 OutputResourcePtr output(int i) const { return outputs_[i]; } 00139 00142 int num_output_partitions() const; 00143 const CachedResult* output_partition(int i) const; 00144 CachedResult* output_partition(int i); 00145 00148 bool chained() const { return chained_; } 00149 00153 void AddSlot(const ResourceSlotPtr& slot); 00154 00157 void RemoveLastSlot(); 00158 00169 void Initiate(); 00170 00178 bool Fetch(const OutputResourcePtr& output_resource, 00179 AsyncFetch* fetch, 00180 MessageHandler* message_handler); 00181 00195 static bool LookupMetadataForOutputResource( 00196 const GoogleString& url, 00197 RewriteDriver* driver, 00198 GoogleString* error_out, 00199 CacheLookupResultCallback* callback); 00200 00224 void Propagate(bool render_slots); 00225 00228 bool slow() const { return slow_; } 00229 00231 bool has_parent() const { return parent_ != NULL; } 00232 00234 RewriteContext* parent() { return parent_; } 00235 const RewriteContext* parent() const { return parent_; } 00236 00239 void AddNestedContext(RewriteContext* context); 00240 00242 void set_force_rewrite(bool x) { force_rewrite_ = x; } 00243 00244 const ResourceContext* resource_context() const { 00245 return resource_context_.get(); 00246 } 00247 00252 void DetachSlots(); 00253 00255 GoogleString ToString(StringPiece prefix) const; 00256 00258 static void InitStats(Statistics* stats); 00259 00260 protected: 00261 typedef std::vector<GoogleUrl*> GoogleUrlStarVector; 00262 00265 void AttachDependentRequestTrace(const StringPiece& label); 00266 00270 RequestTrace* dependent_request_trace() { return dependent_request_trace_; } 00271 00274 void TracePrintf(const char* fmt, ...); 00275 00277 00281 ServerContext* FindServerContext() const; 00282 const RewriteOptions* Options() const; 00283 RewriteDriver* Driver() const; 00284 00287 void AddRecheckDependency(); 00288 00292 void RenderPartitionOnDetach(int partition_index); 00293 00298 void RewriteDone(RewriteResult result, int partition_index); 00299 00304 void NestedRewriteDone(const RewriteContext* context); 00305 00309 void StartNestedTasks(); 00310 00316 bool CreateOutputResourceForCachedOutput(const CachedResult* cached_result, 00317 bool force_hash_to_zero, 00318 OutputResourcePtr* output_resource); 00319 00323 virtual bool OptimizationOnly() const { return true; } 00324 00342 virtual bool Partition(OutputPartitions* partitions, 00343 OutputResourceVector* outputs); 00344 00350 virtual void PartitionAsync(OutputPartitions* partitions, 00351 OutputResourceVector* outputs); 00352 00356 void PartitionDone(bool result); 00357 00360 void CrossThreadPartitionDone(bool result); 00361 00373 virtual void Rewrite(int partition_index, 00374 CachedResult* partition, 00375 const OutputResourcePtr& output) = 0; 00376 00381 virtual void Harvest(); 00382 00394 virtual void Render(); 00395 00398 00405 virtual const UrlSegmentEncoder* encoder() const; 00406 00409 virtual GoogleString CacheKeySuffix() const; 00410 00412 virtual const char* id() const = 0; 00413 00422 virtual OutputResourceKind kind() const = 0; 00423 00433 virtual void StartFetchReconstruction(); 00434 00440 void DetachFetch(); 00441 00446 virtual bool DecodeFetchUrls(const OutputResourcePtr& output_resource, 00447 MessageHandler* message_handler, 00448 GoogleUrlStarVector* url_vector); 00449 00453 virtual void FixFetchFallbackHeaders(ResponseHeaders* headers); 00454 00457 virtual void FetchCallbackDone(bool success); 00458 00465 virtual bool AbsolutifyIfNeeded(const StringPiece& input_contents, 00466 Writer* writer, MessageHandler* handler); 00467 00472 virtual void FetchTryFallback(const GoogleString& url, 00473 const StringPiece& hash); 00474 00476 void Freshen(); 00477 00479 int num_nested() const { return nested_.size(); } 00480 RewriteContext* nested(int i) const { return nested_[i]; } 00481 00482 OutputPartitions* partitions() { return partitions_.get(); } 00483 00484 void set_notify_driver_on_fetch_done(bool value) { 00485 notify_driver_on_fetch_done_ = value; 00486 } 00487 00489 AsyncFetch* async_fetch(); 00490 00492 bool FetchContextDetached(); 00493 00495 MessageHandler* fetch_message_handler(); 00496 00498 bool stale_rewrite() const { return stale_rewrite_; } 00499 00503 virtual int64 GetRewriteDeadlineAlarmMs() const; 00504 00510 virtual GoogleString UserAgentCacheKey( 00511 const ResourceContext* context) const { 00512 return ""; 00513 } 00514 00519 virtual void EncodeUserAgentIntoResourceContext(ResourceContext* context) {} 00520 00521 private: 00522 class OutputCacheCallback; 00523 class LookupMetadataForOutputResourceCallback; 00524 friend class OutputCacheCallback; 00525 class HTTPCacheCallback; 00526 friend class HTTPCacheCallback; 00527 class ResourceCallbackUtils; 00528 friend class ResourceCallbackUtils; 00529 class ResourceFetchCallback; 00530 class ResourceReconstructCallback; 00531 class ResourceRevalidateCallback; 00532 friend class ResourceRevalidateCallback; 00533 class InvokeRewriteFunction; 00534 friend class InvokeRewriteFunction; 00535 class RewriteFreshenCallback; 00536 00537 typedef std::set<RewriteContext*> ContextSet; 00538 00542 enum FallbackCondition { 00543 kFallbackDiscretional, 00544 00545 kFallbackEmergency 00546 00547 }; 00548 00550 void Start(); 00551 void SetPartitionKey(); 00552 void StartFetch(); 00553 void CancelFetch(); 00554 void OutputCacheDone(CacheLookupResult* cache_result); 00555 void OutputCacheHit(bool write_partitions); 00556 void OutputCacheRevalidate(const InputInfoStarVector& to_revalidate); 00557 void OutputCacheMiss(); 00558 void ResourceFetchDone(bool success, ResourcePtr resource, int slot_index); 00559 void ResourceRevalidateDone(InputInfo* input_info, bool success); 00560 void LogMetadataCacheInfo(bool cache_ok, bool can_revalidate); 00561 00566 void RepeatedSuccess(const RewriteContext* primary); 00567 void RepeatedFailure(); 00568 00577 void Finalize(); 00578 00580 NamedLock* Lock(); 00581 00591 void FetchInputs(); 00592 00596 void Activate(); 00597 00604 void StartRewriteForHtml(); 00605 void StartRewriteForFetch(); 00606 00613 bool ReadyToRewrite() const; 00614 00617 void RunSuccessors(); 00618 00621 void WritePartition(); 00622 00632 void FinalizeRewriteForHtml(); 00633 00639 void RetireRewriteForHtml(bool permit_render); 00640 00643 void MarkSlow(); 00644 00647 void MarkTooBusy(); 00648 00652 void CollectDependentTopLevel(ContextSet* contexts); 00653 00656 void RewriteDoneImpl(RewriteResult result, int partition_index); 00657 00660 void StartNestedTasksImpl(); 00661 00664 bool PrepareFetch( 00665 const OutputResourcePtr& output_resource, 00666 AsyncFetch* fetch, 00667 MessageHandler* message_handler); 00668 00670 void FetchCacheDone(CacheLookupResult* cache_result); 00671 00674 void FetchFallbackCacheDone(HTTPCache::FindResult result, 00675 HTTPCache::Callback* data); 00676 00681 bool CanFetchFallbackToOriginal(FallbackCondition circumstance) const; 00682 00685 virtual bool do_stale_rewrite() const { return true; } 00686 00688 ResourceSlotVector slots_; 00689 00693 std::vector<bool> render_slots_; 00694 00705 00706 bool started_; 00707 scoped_ptr<OutputPartitions> partitions_; 00708 OutputResourceVector outputs_; 00709 int outstanding_fetches_; 00710 int outstanding_rewrites_; 00711 scoped_ptr<ResourceContext> resource_context_; 00712 GoogleString partition_key_; 00713 00714 UrlSegmentEncoder default_encoder_; 00715 00718 scoped_ptr<NamedLock> lock_; 00719 00723 class FetchContext; 00724 scoped_ptr<FetchContext> fetch_; 00725 00728 std::vector<RewriteContext*> successors_; 00729 00733 std::vector<RewriteContext*> repeated_; 00734 00738 int num_pending_nested_; 00739 std::vector<RewriteContext*> nested_; 00740 00742 RewriteContext* parent_; 00743 00753 RewriteDriver* driver_; 00754 00756 int num_predecessors_; 00757 00760 bool chained_; 00761 00779 00781 bool rewrite_done_; 00782 00787 bool ok_to_write_output_partitions_; 00788 00791 bool was_too_busy_; 00792 00796 bool slow_; 00797 00799 bool revalidate_ok_; 00800 00803 bool notify_driver_on_fetch_done_; 00804 00807 bool force_rewrite_; 00808 00811 bool stale_rewrite_; 00812 00815 RequestTrace* dependent_request_trace_; 00816 00817 DISALLOW_COPY_AND_ASSIGN(RewriteContext); 00818 }; 00819 00820 } 00821 00822 #endif ///< NET_INSTAWEB_REWRITER_PUBLIC_REWRITE_CONTEXT_H_