153 lines
4.6 KiB
C++
153 lines
4.6 KiB
C++
/*
|
|
* 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: x.dinic@gmail.com(Junmin Xiong)
|
|
//
|
|
// 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 "net/instaweb/http/public/url_async_fetcher.h"
|
|
#include "net/instaweb/util/public/basictypes.h"
|
|
#include "net/instaweb/util/public/pool.h"
|
|
#include "net/instaweb/util/public/string.h"
|
|
#include "net/instaweb/util/public/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
|
|
// initializations which can't be done in the master process
|
|
bool Init();
|
|
|
|
// shutdown all the fetches.
|
|
virtual void ShutDown();
|
|
|
|
virtual bool SupportsHttps() const { return false; }
|
|
|
|
virtual void Fetch(const GoogleString& url,
|
|
MessageHandler* message_handler,
|
|
AsyncFetch* callback);
|
|
|
|
// send the command from the current thread to main thread
|
|
bool SendCmd(const char command);
|
|
// the read handler in the main thread
|
|
static void CommandHandler(ngx_event_t* cmdev);
|
|
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_connection_t* command_connection_; // the command pipe
|
|
int pipe_fd_; // the write pipe end
|
|
ngx_resolver_t* resolver_;
|
|
int max_keepalive_requests_;
|
|
ngx_msec_t resolver_timeout_;
|
|
ngx_msec_t fetch_timeout_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(NgxUrlAsyncFetcher);
|
|
};
|
|
|
|
} // namespace net_instaweb
|
|
|
|
#endif // NET_INSTAWEB_NGX_URL_ASYNC_FETCHER_H_$
|