| /* |
| * Copyright 2012 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| // Author: nikhilmadan@google.com (Nikhil Madan) |
| |
| #ifndef NET_INSTAWEB_HTTP_PUBLIC_RATE_CONTROLLER_H_ |
| #define NET_INSTAWEB_HTTP_PUBLIC_RATE_CONTROLLER_H_ |
| |
| #include <map> |
| |
| #include "pagespeed/kernel/base/atomic_bool.h" |
| #include "pagespeed/kernel/base/basictypes.h" |
| #include "pagespeed/kernel/base/ref_counted_ptr.h" |
| #include "pagespeed/kernel/base/scoped_ptr.h" |
| #include "pagespeed/kernel/base/string.h" |
| |
| namespace net_instaweb { |
| |
| class AbstractMutex; |
| class AsyncFetch; |
| class MessageHandler; |
| class Statistics; |
| class ThreadSystem; |
| class TimedVariable; |
| class UpDownCounter; |
| class UrlAsyncFetcher; |
| |
| // Controller which limits the number of outgoing fetches per domain. If the |
| // fetch is for a user-facing request, this sends the request out anyway and |
| // updates the count for number of outgoing fetches. |
| // For non-user facing requests, this checks that the number of outgoing fetches |
| // for this domain is less than the limit. If less than the limit, it sends |
| // the fetch out and updates the count. If greater than the per-domain limit, |
| // and if the global queue size is within the limit, it queues the request up. |
| // However, if the global queue size is above the limit, it drops the request. |
| // If a request is dropped, the response will have HttpAttributes::kXPsaLoadShed |
| // set on the response headers. |
| // |
| // Note: this requires working statistics to work. |
| class RateController { |
| public: |
| static const char kQueuedFetchCount[]; |
| static const char kDroppedFetchCount[]; |
| static const char kCurrentGlobalFetchQueueSize[]; |
| |
| RateController(int max_global_queue_size, |
| int per_host_outgoing_request_threshold, |
| int per_host_queued_request_threshold, |
| ThreadSystem* thread_system, |
| Statistics* statistics); |
| |
| virtual ~RateController(); |
| |
| // Makes any further fetches quick-fail. |
| void ShutDown() { shutdown_.set_value(true); } |
| bool is_shut_down() const { return shutdown_.value(); } |
| |
| // Applies our shaping policies, and either (eventually) asks fetcher to |
| // fetch the given URL or drops it. |
| void Fetch(UrlAsyncFetcher* fetcher, |
| const GoogleString& url, |
| MessageHandler* message_handler, |
| AsyncFetch* fetch); |
| |
| // Initializes statistics variables associated with this class. |
| static void InitStats(Statistics* statistics); |
| |
| private: |
| class HostFetchInfo; |
| class CustomFetch; |
| friend class CustomFetch; |
| |
| typedef RefCountedPtr<HostFetchInfo> HostFetchInfoPtr; |
| |
| typedef std::map<GoogleString, HostFetchInfoPtr*> HostFetchInfoMap; |
| |
| // Delete the fetch info from fetch_info_map_ if possible. |
| void DeleteFetchInfoIfPossible(const HostFetchInfoPtr& fetch_info); |
| |
| // The maximum permissible size of the global queue. |
| const int max_global_queue_size_; |
| // The maximum number of outgoing requests allowed per host. |
| const int per_host_outgoing_request_threshold_; |
| // The maximum number of queued requests allowed per host. |
| const int per_host_queued_request_threshold_; |
| ThreadSystem* thread_system_; |
| |
| // Map containing per-host information tracking outgoing and queued fetches. |
| HostFetchInfoMap fetch_info_map_; |
| scoped_ptr<AbstractMutex> mutex_; |
| |
| TimedVariable* queued_fetch_count_; |
| TimedVariable* dropped_fetch_count_; |
| // Using a variable here, since we want to be able to track this in the server |
| // statistics. |
| UpDownCounter* current_global_fetch_queue_size_; |
| |
| AtomicBool shutdown_; |
| |
| DISALLOW_COPY_AND_ASSIGN(RateController); |
| }; |
| |
| } // namespace net_instaweb |
| |
| #endif // NET_INSTAWEB_HTTP_PUBLIC_RATE_CONTROLLER_H_ |