Neon C++: cache Session
Starting a neon Session is slow, in particular when libproxy is involved (seems to search for proxy servers, which involves a DNS timeout when none are around). Another delay is opening the TCP connection and determining which kind of autentication is needed. For a normal program run there's not much that can be done to speed this up, but in client-test it helps a lot to reuse an existing Session instance between different tests. This patch enables that by keeping one Session instance around and returning that if the new one has the same parameters. The Settings pointer is a boost::shared_ptr, but this patch avoids using it unless the Session is in active use, just in case that a user wants to merge the settings into a class with a different life time.
This commit is contained in:
parent
9b1a91ee23
commit
46e9bf84e1
3 changed files with 44 additions and 5 deletions
|
@ -192,11 +192,11 @@ Session::Session(const boost::shared_ptr<Settings> &settings) :
|
|||
}
|
||||
}
|
||||
|
||||
std::string proxyurl = settings->proxy();
|
||||
if (proxyurl.empty()) {
|
||||
m_proxyURL = settings->proxy();
|
||||
if (m_proxyURL.empty()) {
|
||||
ne_session_system_proxy(m_session, 0);
|
||||
} else {
|
||||
URI proxyuri = URI::parse(proxyurl);
|
||||
URI proxyuri = URI::parse(m_proxyURL);
|
||||
ne_session_proxy(m_session, proxyuri.m_host.c_str(), proxyuri.m_port);
|
||||
}
|
||||
}
|
||||
|
@ -209,6 +209,24 @@ Session::~Session()
|
|||
ne_sock_exit();
|
||||
}
|
||||
|
||||
boost::shared_ptr<Session> Session::m_cachedSession;
|
||||
|
||||
boost::shared_ptr<Session> Session::create(const boost::shared_ptr<Settings> &settings)
|
||||
{
|
||||
URI uri = URI::parse(settings->getURL());
|
||||
if (m_cachedSession &&
|
||||
m_cachedSession->m_uri == uri &&
|
||||
m_cachedSession->m_proxyURL == settings->proxy()) {
|
||||
// reuse existing session with new settings pointer
|
||||
m_cachedSession->m_settings = settings;
|
||||
return m_cachedSession;
|
||||
}
|
||||
// create new session
|
||||
m_cachedSession.reset(new Session(settings));
|
||||
return m_cachedSession;
|
||||
}
|
||||
|
||||
|
||||
int Session::getCredentials(void *userdata, const char *realm, int attempt, char *username, char *password) throw()
|
||||
{
|
||||
try {
|
||||
|
|
|
@ -132,6 +132,16 @@ struct URI {
|
|||
* doesn't have a trailing slash.
|
||||
*/
|
||||
static std::string normalizePath(const std::string &path, bool collection);
|
||||
|
||||
bool operator == (const URI &other) {
|
||||
return m_scheme == other.m_scheme &&
|
||||
m_host == other.m_host &&
|
||||
m_userinfo == other.m_userinfo &&
|
||||
m_port == other.m_port &&
|
||||
m_path == other.m_path &&
|
||||
m_query == other.m_query &&
|
||||
m_fragment == other.m_fragment;
|
||||
}
|
||||
};
|
||||
|
||||
/** produce debug string for status, which may be NULL */
|
||||
|
@ -142,11 +152,21 @@ std::string Status2String(const ne_status *status);
|
|||
* Throws transport errors for fatal problems.
|
||||
*/
|
||||
class Session {
|
||||
public:
|
||||
/**
|
||||
* @param settings must provide information about settings on demand
|
||||
*/
|
||||
Session(const boost::shared_ptr<Settings> &settings);
|
||||
static boost::shared_ptr<Session> m_cachedSession;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create or reuse Session instance.
|
||||
*
|
||||
* One Session instance is kept alive throughout the life of the process,
|
||||
* to reuse proxy information (libproxy has a considerably delay during
|
||||
* initialization) and HTTP connection/authentication.
|
||||
*/
|
||||
static boost::shared_ptr<Session> create(const boost::shared_ptr<Settings> &settings);
|
||||
~Session();
|
||||
|
||||
/** ne_options2() */
|
||||
|
@ -194,6 +214,7 @@ class Session {
|
|||
boost::shared_ptr<Settings> m_settings;
|
||||
ne_session *m_session;
|
||||
URI m_uri;
|
||||
std::string m_proxyURL;
|
||||
time_t m_lastRequestEnd;
|
||||
|
||||
/** ne_set_server_auth() callback */
|
||||
|
|
|
@ -127,7 +127,7 @@ void WebDAVSource::open()
|
|||
{
|
||||
SE_LOG_DEBUG(NULL, NULL, "using libneon %s with %s",
|
||||
ne_version_string(), Neon::features().c_str());
|
||||
m_session.reset(new Neon::Session(m_settings));
|
||||
m_session = Neon::Session::create(m_settings);
|
||||
|
||||
// Start by checking server capabilities.
|
||||
// Verifies URL.
|
||||
|
|
Loading…
Reference in a new issue