Page Speed Optimization Libraries  1.5.27.2
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 
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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines