Page Speed Optimization Libraries  1.6.29.3
net/instaweb/rewriter/public/rewrite_context.h
Go to the documentation of this file.
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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines