Page Speed Optimization Libraries  1.4.26.1
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 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 
00248   bool is_metadata_cache_miss() const { return is_metadata_cache_miss_; }
00249 
00250   bool rewrite_uncacheable() const { return rewrite_uncacheable_; }
00251   void set_rewrite_uncacheable(bool rewrite_uncacheable) {
00252     rewrite_uncacheable_ = rewrite_uncacheable;
00253   }
00254 
00259   void DetachSlots();
00260 
00262   GoogleString ToString(StringPiece prefix) const;
00263 
00265   static void InitStats(Statistics* stats);
00266 
00267  protected:
00268   typedef std::vector<GoogleUrl*> GoogleUrlStarVector;
00269 
00272   void AttachDependentRequestTrace(const StringPiece& label);
00273 
00277   RequestTrace* dependent_request_trace() { return dependent_request_trace_; }
00278 
00281   void TracePrintf(const char* fmt, ...);
00282 
00284 
00288   ServerContext* FindServerContext() const;
00289   const RewriteOptions* Options() const;
00290   RewriteDriver* Driver() const;
00291 
00294   void AddRecheckDependency();
00295 
00299   void RenderPartitionOnDetach(int partition_index);
00300 
00305   void RewriteDone(RewriteResult result, int partition_index);
00306 
00311   void NestedRewriteDone(const RewriteContext* context);
00312 
00316   void StartNestedTasks();
00317 
00323   bool CreateOutputResourceForCachedOutput(const CachedResult* cached_result,
00324                                            bool force_hash_to_zero,
00325                                            OutputResourcePtr* output_resource);
00326 
00330   virtual bool OptimizationOnly() const { return true; }
00331 
00349   virtual bool Partition(OutputPartitions* partitions,
00350                          OutputResourceVector* outputs);
00351 
00357   virtual void PartitionAsync(OutputPartitions* partitions,
00358                               OutputResourceVector* outputs);
00359 
00363   void PartitionDone(bool result);
00364 
00367   void CrossThreadPartitionDone(bool result);
00368 
00380   virtual void Rewrite(int partition_index,
00381                        CachedResult* partition,
00382                        const OutputResourcePtr& output) = 0;
00383 
00388   virtual void Harvest();
00389 
00401   virtual void Render();
00402 
00405 
00412   virtual const UrlSegmentEncoder* encoder() const;
00413 
00416   virtual GoogleString CacheKeySuffix() const;
00417 
00419   virtual const char* id() const = 0;
00420 
00429   virtual OutputResourceKind kind() const = 0;
00430 
00440   virtual void StartFetchReconstruction();
00441 
00447   void DetachFetch();
00448 
00453   virtual bool DecodeFetchUrls(const OutputResourcePtr& output_resource,
00454                                MessageHandler* message_handler,
00455                                GoogleUrlStarVector* url_vector);
00456 
00460   virtual void FixFetchFallbackHeaders(ResponseHeaders* headers);
00461 
00464   virtual void FetchCallbackDone(bool success);
00465 
00472   virtual bool AbsolutifyIfNeeded(const StringPiece& input_contents,
00473                                   Writer* writer, MessageHandler* handler);
00474 
00479   virtual void FetchTryFallback(const GoogleString& url,
00480                                 const StringPiece& hash);
00481 
00483   void Freshen();
00484 
00486   int num_nested() const { return nested_.size(); }
00487   RewriteContext* nested(int i) const { return nested_[i]; }
00488 
00489   OutputPartitions* partitions() { return partitions_.get(); }
00490 
00491   void set_notify_driver_on_fetch_done(bool value) {
00492     notify_driver_on_fetch_done_ = value;
00493   }
00494 
00496   AsyncFetch* async_fetch();
00497 
00499   bool FetchContextDetached();
00500 
00502   MessageHandler* fetch_message_handler();
00503 
00505   bool stale_rewrite() const { return stale_rewrite_; }
00506 
00510   virtual int64 GetRewriteDeadlineAlarmMs() const;
00511 
00517   virtual GoogleString UserAgentCacheKey(
00518       const ResourceContext* context) const {
00519     return "";
00520   }
00521 
00526   virtual void EncodeUserAgentIntoResourceContext(ResourceContext* context) {}
00527 
00528  private:
00529   class OutputCacheCallback;
00530   class LookupMetadataForOutputResourceCallback;
00531   friend class OutputCacheCallback;
00532   class HTTPCacheCallback;
00533   friend class HTTPCacheCallback;
00534   class ResourceCallbackUtils;
00535   friend class ResourceCallbackUtils;
00536   class ResourceFetchCallback;
00537   class ResourceReconstructCallback;
00538   class ResourceRevalidateCallback;
00539   friend class ResourceRevalidateCallback;
00540   class InvokeRewriteFunction;
00541   friend class InvokeRewriteFunction;
00542   class RewriteFreshenCallback;
00543 
00544   typedef std::set<RewriteContext*> ContextSet;
00545 
00549   enum FallbackCondition {
00550     kFallbackDiscretional,   
00551 
00552     kFallbackEmergency    
00553 
00554   };
00555 
00557   void Start();
00558   void SetPartitionKey();
00559   void StartFetch();
00560   void CancelFetch();
00561   void OutputCacheDone(CacheLookupResult* cache_result);
00562   void OutputCacheHit(bool write_partitions);
00563   void OutputCacheRevalidate(const InputInfoStarVector& to_revalidate);
00564   void OutputCacheMiss();
00565   void ResourceFetchDone(bool success, ResourcePtr resource, int slot_index);
00566   void ResourceRevalidateDone(InputInfo* input_info, bool success);
00567   void LogMetadataCacheInfo(bool cache_ok, bool can_revalidate);
00568 
00573   void RepeatedSuccess(const RewriteContext* primary);
00574   void RepeatedFailure();
00575 
00584   void Finalize();
00585 
00587   NamedLock* Lock();
00588 
00598   void FetchInputs();
00599 
00603   void Activate();
00604 
00611   void StartRewriteForHtml();
00612   void StartRewriteForFetch();
00613 
00620   bool ReadyToRewrite() const;
00621 
00624   void RunSuccessors();
00625 
00628   void WritePartition();
00629 
00639   void FinalizeRewriteForHtml();
00640 
00646   void RetireRewriteForHtml(bool permit_render);
00647 
00650   void MarkSlow();
00651 
00654   void MarkTooBusy();
00655 
00659   void CollectDependentTopLevel(ContextSet* contexts);
00660 
00663   void RewriteDoneImpl(RewriteResult result, int partition_index);
00664 
00667   void StartNestedTasksImpl();
00668 
00671   bool PrepareFetch(
00672       const OutputResourcePtr& output_resource,
00673       AsyncFetch* fetch,
00674       MessageHandler* message_handler);
00675 
00677   void FetchCacheDone(CacheLookupResult* cache_result);
00678 
00681   void FetchFallbackCacheDone(HTTPCache::FindResult result,
00682                               HTTPCache::Callback* data);
00683 
00688   bool CanFetchFallbackToOriginal(FallbackCondition circumstance) const;
00689 
00692   virtual bool do_stale_rewrite() const { return true; }
00693 
00695   ResourceSlotVector slots_;
00696 
00700   std::vector<bool> render_slots_;
00701 
00712 
00713   bool started_;
00714   scoped_ptr<OutputPartitions> partitions_;
00715   OutputResourceVector outputs_;
00716   int outstanding_fetches_;
00717   int outstanding_rewrites_;
00718   scoped_ptr<ResourceContext> resource_context_;
00719   GoogleString partition_key_;
00720 
00721   UrlSegmentEncoder default_encoder_;
00722 
00725   scoped_ptr<NamedLock> lock_;
00726 
00730   class FetchContext;
00731   scoped_ptr<FetchContext> fetch_;
00732 
00735   std::vector<RewriteContext*> successors_;
00736 
00740   std::vector<RewriteContext*> repeated_;
00741 
00745   int num_pending_nested_;
00746   std::vector<RewriteContext*> nested_;
00747 
00749   RewriteContext* parent_;
00750 
00760   RewriteDriver* driver_;
00761 
00763   int num_predecessors_;
00764 
00767   bool chained_;
00768 
00786 
00788   bool rewrite_done_;
00789 
00794   bool ok_to_write_output_partitions_;
00795 
00798   bool was_too_busy_;
00799 
00803   bool slow_;
00804 
00806   bool revalidate_ok_;
00807 
00810   bool notify_driver_on_fetch_done_;
00811 
00814   bool force_rewrite_;
00815 
00818   bool stale_rewrite_;
00819 
00822   bool is_metadata_cache_miss_;
00823 
00826   bool rewrite_uncacheable_;
00827 
00830   RequestTrace* dependent_request_trace_;
00831 
00832   DISALLOW_COPY_AND_ASSIGN(RewriteContext);
00833 };
00834 
00835 }  
00836 
00837 #endif  ///< NET_INSTAWEB_REWRITER_PUBLIC_REWRITE_CONTEXT_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines