blob: db7f6f7ffcab141c0a88ddcc078d5ee5006130a3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
//
// Fetch the resources asynchronously in Nginx. The fetcher is called in
// the rewrite thread.
//
// It can communicate with Nginx by pipe. One pipe for one fetcher.
// When new url fetch comes, Fetcher will add it to the pending queue and
// notify the Nginx thread to start the Fetch event. All the events are hooked
// in the main thread's epoll structure.
#ifndef NET_INSTAWEB_NGX_URL_ASYNC_FETCHER_H_
#define NET_INSTAWEB_NGX_URL_ASYNC_FETCHER_H_
extern "C" {
#include <ngx_config.h>
#include <ngx_core.h>
}
#include <vector>
#include "ngx_event_connection.h"
#include "net/instaweb/http/public/url_async_fetcher.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/pool.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/thread_system.h"
namespace net_instaweb {
class AsyncFetch;
class MessageHandler;
class Statistics;
class NgxFetch;
class Variable;
class NgxUrlAsyncFetcher : public UrlAsyncFetcher {
public:
NgxUrlAsyncFetcher(
const char* proxy, ngx_log_t* log, ngx_msec_t resolver_timeout,
ngx_msec_t fetch_timeout, ngx_resolver_t* resolver,
int max_keepalive_requests, ThreadSystem* thread_system,
MessageHandler* handler);
~NgxUrlAsyncFetcher();
// It should be called in the module init_process callback function. Do some
// intializations which can't be done in the master process
bool Init(ngx_cycle_t* cycle);
// shutdown all the fetches.
virtual void ShutDown();
// the read handler in the main thread
static void ReadCallback(const ps_event_data& data);
virtual bool SupportsHttps() const { return false; }
virtual void Fetch(const GoogleString& url,
MessageHandler* message_handler,
AsyncFetch* callback);
bool StartFetch(NgxFetch* fetch);
// Remove the completed fetch from the active fetch set, and put it into a
// completed fetch list to be cleaned up.
void FetchComplete(NgxFetch* fetch);
void PrintActiveFetches(MessageHandler* handler) const;
// Indicates that it should track the original content length for
// fetched resources.
bool track_original_content_length() {
return track_original_content_length_;
}
void set_track_original_content_length(bool x) {
track_original_content_length_ = x;
}
typedef Pool<NgxFetch> NgxFetchPool;
// AnyPendingFetches is accurate only at the time of call; this is
// used conservatively during shutdown. It counts fetches that have been
// requested by some thread, and can include fetches for which no action
// has yet been taken (ie fetches that are not active).
virtual bool AnyPendingFetches() {
return !active_fetches_.empty();
}
// ApproximateNumActiveFetches can under- or over-count and is used only for
// error reporting.
int ApproximateNumActiveFetches() {
return active_fetches_.size();
}
void CancelActiveFetches();
// These must be accessed with mutex_ held.
bool shutdown() const { return shutdown_; }
void set_shutdown(bool s) { shutdown_ = s; }
private:
static void TimeoutHandler(ngx_event_t* tev);
static bool ParseUrl(ngx_url_t* url, ngx_pool_t* pool);
friend class NgxFetch;
NgxFetchPool active_fetches_;
// Add the pending task to this list
NgxFetchPool pending_fetches_;
NgxFetchPool completed_fetches_;
ngx_url_t proxy_;
int fetchers_count_;
bool shutdown_;
bool track_original_content_length_;
int64 byte_count_;
ThreadSystem* thread_system_;
MessageHandler* message_handler_;
// Protect the member variable in this class
// active_fetches, pending_fetches
ThreadSystem::CondvarCapableMutex* mutex_;
ngx_pool_t* pool_;
ngx_log_t* log_;
ngx_resolver_t* resolver_;
int max_keepalive_requests_;
ngx_msec_t resolver_timeout_;
ngx_msec_t fetch_timeout_;
NgxEventConnection* event_connection_;
DISALLOW_COPY_AND_ASSIGN(NgxUrlAsyncFetcher);
};
} // namespace net_instaweb
#endif // NET_INSTAWEB_NGX_URL_ASYNC_FETCHER_H_$