* i2p::fs migration: Profiling.*

This commit is contained in:
hagen 2016-02-11 00:00:00 +00:00
parent 2b137b43e6
commit bfcb6f577f
2 changed files with 73 additions and 115 deletions

View File

@ -1,8 +1,8 @@
#include <boost/filesystem.hpp> #include <sys/stat.h>
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp> #include <boost/property_tree/ini_parser.hpp>
#include "Base.h" #include "Base.h"
#include "util.h" #include "FS.h"
#include "Log.h" #include "Log.h"
#include "Profiling.h" #include "Profiling.h"
@ -41,101 +41,69 @@ namespace data
boost::property_tree::ptree pt; boost::property_tree::ptree pt;
pt.put (PEER_PROFILE_LAST_UPDATE_TIME, boost::posix_time::to_simple_string (m_LastUpdateTime)); pt.put (PEER_PROFILE_LAST_UPDATE_TIME, boost::posix_time::to_simple_string (m_LastUpdateTime));
pt.put_child (PEER_PROFILE_SECTION_PARTICIPATION, participation); pt.put_child (PEER_PROFILE_SECTION_PARTICIPATION, participation);
pt.put_child (PEER_PROFILE_SECTION_USAGE, usage); pt.put_child (PEER_PROFILE_SECTION_USAGE, usage);
// save to file // save to file
auto path = i2p::util::filesystem::GetDefaultDataDir() / PEER_PROFILES_DIRECTORY; std::string ident = m_IdentHash.ToBase64 ();
if (!boost::filesystem::exists (path)) std::string path = i2p::fs::GetPeerProfiles().Path(ident);
{
// Create directory is necessary try {
if (!boost::filesystem::create_directory (path)) boost::property_tree::write_ini (path, pt);
{ } catch (std::exception& ex) {
LogPrint (eLogError, "Failed to create directory ", path); /* boost exception verbose enough */
return; LogPrint (eLogError, "Profiling: ", ex.what ());
}
const char * chars = GetBase64SubstitutionTable (); // 64 bytes
for (int i = 0; i < 64; i++)
{
auto path1 = path / (std::string ("p") + chars[i]);
if (!boost::filesystem::exists (path1) && !boost::filesystem::create_directory (path1))
{
LogPrint (eLogError, "Failed to create directory ", path1);
return;
}
}
} }
std::string base64 = m_IdentHash.ToBase64 (); }
path = path / (std::string ("p") + base64[0]);
auto filename = path / (std::string (PEER_PROFILE_PREFIX) + base64 + ".txt");
try
{
boost::property_tree::write_ini (filename.string (), pt);
}
catch (std::exception& ex)
{
LogPrint (eLogError, "Can't write ", filename, ": ", ex.what ());
}
}
void RouterProfile::Load () void RouterProfile::Load ()
{ {
std::string base64 = m_IdentHash.ToBase64 (); std::string ident = m_IdentHash.ToBase64 ();
auto path = i2p::util::filesystem::GetDefaultDataDir() / PEER_PROFILES_DIRECTORY; std::string path = i2p::fs::GetPeerProfiles().Path(ident);
path /= std::string ("p") + base64[0]; boost::property_tree::ptree pt;
auto filename = path / (std::string (PEER_PROFILE_PREFIX) + base64 + ".txt");
if (boost::filesystem::exists (filename)) if (!i2p::fs::Exists(path)) {
{ LogPrint(eLogWarning, "Profiling: no profile yet for ", ident);
boost::property_tree::ptree pt; return;
try }
{
boost::property_tree::read_ini (filename.string (), pt); try {
} boost::property_tree::read_ini (path, pt);
catch (std::exception& ex) } catch (std::exception& ex) {
{ /* boost exception verbose enough */
LogPrint (eLogError, "Can't read ", filename, ": ", ex.what ()); LogPrint (eLogError, "Profiling: ", ex.what ());
return; return;
} }
try
{ try {
auto t = pt.get (PEER_PROFILE_LAST_UPDATE_TIME, ""); auto t = pt.get (PEER_PROFILE_LAST_UPDATE_TIME, "");
if (t.length () > 0) if (t.length () > 0)
m_LastUpdateTime = boost::posix_time::time_from_string (t); m_LastUpdateTime = boost::posix_time::time_from_string (t);
if ((GetTime () - m_LastUpdateTime).hours () < PEER_PROFILE_EXPIRATION_TIMEOUT) if ((GetTime () - m_LastUpdateTime).hours () < PEER_PROFILE_EXPIRATION_TIMEOUT) {
{ try {
try // read participations
{ auto participations = pt.get_child (PEER_PROFILE_SECTION_PARTICIPATION);
// read participations m_NumTunnelsAgreed = participations.get (PEER_PROFILE_PARTICIPATION_AGREED, 0);
auto participations = pt.get_child (PEER_PROFILE_SECTION_PARTICIPATION); m_NumTunnelsDeclined = participations.get (PEER_PROFILE_PARTICIPATION_DECLINED, 0);
m_NumTunnelsAgreed = participations.get (PEER_PROFILE_PARTICIPATION_AGREED, 0); m_NumTunnelsNonReplied = participations.get (PEER_PROFILE_PARTICIPATION_NON_REPLIED, 0);
m_NumTunnelsDeclined = participations.get (PEER_PROFILE_PARTICIPATION_DECLINED, 0); } catch (boost::property_tree::ptree_bad_path& ex) {
m_NumTunnelsNonReplied = participations.get (PEER_PROFILE_PARTICIPATION_NON_REPLIED, 0); LogPrint (eLogWarning, "Profiling: Missing section ", PEER_PROFILE_SECTION_PARTICIPATION, " in profile for ", ident);
}
catch (boost::property_tree::ptree_bad_path& ex)
{
LogPrint (eLogWarning, "Missing section ", PEER_PROFILE_SECTION_PARTICIPATION);
}
try
{
// read usage
auto usage = pt.get_child (PEER_PROFILE_SECTION_USAGE);
m_NumTimesTaken = usage.get (PEER_PROFILE_USAGE_TAKEN, 0);
m_NumTimesRejected = usage.get (PEER_PROFILE_USAGE_REJECTED, 0);
}
catch (boost::property_tree::ptree_bad_path& ex)
{
LogPrint (eLogWarning, "Missing section ", PEER_PROFILE_SECTION_USAGE);
}
} }
else try {
*this = RouterProfile (m_IdentHash); // read usage
} auto usage = pt.get_child (PEER_PROFILE_SECTION_USAGE);
catch (std::exception& ex) m_NumTimesTaken = usage.get (PEER_PROFILE_USAGE_TAKEN, 0);
{ m_NumTimesRejected = usage.get (PEER_PROFILE_USAGE_REJECTED, 0);
LogPrint (eLogError, "Can't read profile ", base64, " :", ex.what ()); } catch (boost::property_tree::ptree_bad_path& ex) {
} LogPrint (eLogWarning, "Missing section ", PEER_PROFILE_SECTION_USAGE, " in profile for ", ident);
} }
} } else {
*this = RouterProfile (m_IdentHash);
}
} catch (std::exception& ex) {
LogPrint (eLogError, "Profiling: Can't read profile ", ident, " :", ex.what ());
}
}
void RouterProfile::TunnelBuildResponse (uint8_t ret) void RouterProfile::TunnelBuildResponse (uint8_t ret)
{ {
UpdateTime (); UpdateTime ();
@ -186,29 +154,21 @@ namespace data
void DeleteObsoleteProfiles () void DeleteObsoleteProfiles ()
{ {
int num = 0; struct stat st;
auto ts = boost::posix_time::second_clock::local_time(); std::time_t now = std::time(nullptr);
boost::filesystem::path p (i2p::util::filesystem::GetDataDir()/PEER_PROFILES_DIRECTORY);
if (boost::filesystem::exists (p)) std::vector<std::string> files;
{ i2p::fs::GetPeerProfiles().Traverse(files);
boost::filesystem::directory_iterator end; for (auto path: files) {
for (boost::filesystem::directory_iterator it (p); it != end; ++it) if (stat(path.c_str(), &st) != 0) {
{ LogPrint(eLogWarning, "Profiling: Can't stat(): ", path);
if (boost::filesystem::is_directory (it->status())) continue;
{ }
for (boost::filesystem::directory_iterator it1 (it->path ()); it1 != end; ++it1) if (((now - st.st_mtime) / 3600) >= PEER_PROFILE_EXPIRATION_TIMEOUT) {
{ LogPrint(eLogDebug, "Profiling: removing expired peer profile: ", path);
auto lastModified = boost::posix_time::from_time_t (boost::filesystem::last_write_time (it1->path ())); i2p::fs::Remove(path);
if ((ts - lastModified).hours () >= PEER_PROFILE_EXPIRATION_TIMEOUT) }
{
boost::filesystem::remove (it1->path ());
num++;
}
}
}
}
} }
LogPrint (eLogInfo, num, " obsolete profiles deleted"); }
}
} }
} }

View File

@ -9,8 +9,6 @@ namespace i2p
{ {
namespace data namespace data
{ {
const char PEER_PROFILES_DIRECTORY[] = "peerProfiles";
const char PEER_PROFILE_PREFIX[] = "profile-";
// sections // sections
const char PEER_PROFILE_SECTION_PARTICIPATION[] = "participation"; const char PEER_PROFILE_SECTION_PARTICIPATION[] = "participation";
const char PEER_PROFILE_SECTION_USAGE[] = "usage"; const char PEER_PROFILE_SECTION_USAGE[] = "usage";