mirror of https://github.com/aria2/aria2
Rewritten ServerStatMan using BufferedFile.
parent
7f3d027b83
commit
190d170076
|
@ -39,7 +39,6 @@
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <fstream>
|
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
@ -835,44 +834,12 @@ bool RequestGroupMan::addServerStat(const SharedHandle<ServerStat>& serverStat)
|
||||||
|
|
||||||
bool RequestGroupMan::loadServerStat(const std::string& filename)
|
bool RequestGroupMan::loadServerStat(const std::string& filename)
|
||||||
{
|
{
|
||||||
std::ifstream in(filename.c_str(), std::ios::binary);
|
return serverStatMan_->load(filename);
|
||||||
if(!in) {
|
|
||||||
A2_LOG_ERROR(fmt(MSG_OPENING_READABLE_SERVER_STAT_FILE_FAILED,
|
|
||||||
filename.c_str()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(serverStatMan_->load(in)) {
|
|
||||||
A2_LOG_NOTICE(fmt(MSG_SERVER_STAT_LOADED, filename.c_str()));
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
A2_LOG_ERROR(fmt(MSG_READING_SERVER_STAT_FILE_FAILED, filename.c_str()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RequestGroupMan::saveServerStat(const std::string& filename) const
|
bool RequestGroupMan::saveServerStat(const std::string& filename) const
|
||||||
{
|
{
|
||||||
std::string tempfile = filename;
|
return serverStatMan_->save(filename);
|
||||||
tempfile += "__temp";
|
|
||||||
{
|
|
||||||
std::ofstream out(tempfile.c_str(), std::ios::binary);
|
|
||||||
if(!out) {
|
|
||||||
A2_LOG_ERROR(fmt(MSG_OPENING_WRITABLE_SERVER_STAT_FILE_FAILED,
|
|
||||||
filename.c_str()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(!serverStatMan_->save(out)) {
|
|
||||||
A2_LOG_ERROR(fmt(MSG_WRITING_SERVER_STAT_FILE_FAILED, filename.c_str()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(File(tempfile).renameTo(filename)) {
|
|
||||||
A2_LOG_NOTICE(fmt(MSG_SERVER_STAT_SAVED, filename.c_str()));
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
A2_LOG_ERROR(fmt(MSG_WRITING_SERVER_STAT_FILE_FAILED, filename.c_str()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestGroupMan::removeStaleServerStat(time_t timeout)
|
void RequestGroupMan::removeStaleServerStat(time_t timeout)
|
||||||
|
|
|
@ -41,6 +41,8 @@
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
|
#include "a2functional.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -204,17 +206,20 @@ bool ServerStat::operator==(const ServerStat& serverStat) const
|
||||||
return hostname_ == serverStat.hostname_ && protocol_ == serverStat.protocol_;
|
return hostname_ == serverStat.hostname_ && protocol_ == serverStat.protocol_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& o, const ServerStat& serverStat)
|
std::string ServerStat::toString() const
|
||||||
{
|
{
|
||||||
o << "host=" << serverStat.getHostname() << ", "
|
std::string res;
|
||||||
<< "protocol=" << serverStat.getProtocol() << ", "
|
strappend(res, "host=", getHostname(), ", ");
|
||||||
<< "dl_speed=" << serverStat.getDownloadSpeed() << ", "
|
strappend(res, "protocol=", getProtocol(), ", ");
|
||||||
<< "sc_avg_speed=" << serverStat.getSingleConnectionAvgSpeed() << ", "
|
strappend(res, "dl_speed=", util::uitos(getDownloadSpeed()), ", ");
|
||||||
<< "mc_avg_speed=" << serverStat.getMultiConnectionAvgSpeed() << ", "
|
strappend(res, "sc_avg_speed=", util::uitos(getSingleConnectionAvgSpeed()),
|
||||||
<< "last_updated=" << serverStat.getLastUpdated().getTime() << ", "
|
", ");
|
||||||
<< "counter=" << serverStat.getCounter() << ", "
|
strappend(res, "mc_avg_speed=", util::uitos(getMultiConnectionAvgSpeed()),
|
||||||
<< "status=" << ServerStat::STATUS_STRING[serverStat.getStatus()];
|
", ");
|
||||||
return o;
|
strappend(res, "last_updated=", util::itos(getLastUpdated().getTime()), ", ");
|
||||||
|
strappend(res, "counter=", util::uitos(getCounter()), ", ");
|
||||||
|
strappend(res, "status=", ServerStat::STATUS_STRING[getStatus()]);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -146,6 +146,8 @@ public:
|
||||||
bool operator<(const ServerStat& serverStat) const;
|
bool operator<(const ServerStat& serverStat) const;
|
||||||
|
|
||||||
bool operator==(const ServerStat& serverStat) const;
|
bool operator==(const ServerStat& serverStat) const;
|
||||||
|
|
||||||
|
std::string toString() const;
|
||||||
private:
|
private:
|
||||||
std::string hostname_;
|
std::string hostname_;
|
||||||
|
|
||||||
|
@ -166,8 +168,6 @@ private:
|
||||||
void setStatusInternal(STATUS status);
|
void setStatusInternal(STATUS status);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& o, const ServerStat& serverStat);
|
|
||||||
|
|
||||||
class ServerStatFaster {
|
class ServerStatFaster {
|
||||||
public:
|
public:
|
||||||
bool operator()
|
bool operator()
|
||||||
|
|
|
@ -34,8 +34,9 @@
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "ServerStatMan.h"
|
#include "ServerStatMan.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdio>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <ostream>
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -44,6 +45,11 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "RecoverableException.h"
|
#include "RecoverableException.h"
|
||||||
#include "a2functional.h"
|
#include "a2functional.h"
|
||||||
|
#include "BufferedFile.h"
|
||||||
|
#include "message.h"
|
||||||
|
#include "fmt.h"
|
||||||
|
#include "LogFactory.h"
|
||||||
|
#include "File.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -80,17 +86,44 @@ bool ServerStatMan::add(const SharedHandle<ServerStat>& serverStat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServerStatMan::save(std::ostream& out) const
|
bool ServerStatMan::save(const std::string& filename) const
|
||||||
{
|
{
|
||||||
for(std::deque<SharedHandle<ServerStat> >::const_iterator i =
|
std::string tempfile = filename;
|
||||||
serverStats_.begin(), eoi = serverStats_.end(); i != eoi; ++i) {
|
tempfile += "__temp";
|
||||||
out << *(*i) << "\n";
|
{
|
||||||
|
BufferedFile fp(tempfile, BufferedFile::WRITE);
|
||||||
|
if(!fp) {
|
||||||
|
A2_LOG_ERROR(fmt(MSG_OPENING_WRITABLE_SERVER_STAT_FILE_FAILED,
|
||||||
|
utf8ToNative(filename).c_str()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(std::deque<SharedHandle<ServerStat> >::const_iterator i =
|
||||||
|
serverStats_.begin(), eoi = serverStats_.end(); i != eoi; ++i) {
|
||||||
|
std::string l = (*i)->toString();
|
||||||
|
l += "\n";
|
||||||
|
if(fp.write(l.data(), l.size()) != l.size()) {
|
||||||
|
A2_LOG_ERROR(fmt(MSG_WRITING_SERVER_STAT_FILE_FAILED,
|
||||||
|
utf8ToNative(filename).c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(fp.close() == EOF) {
|
||||||
|
A2_LOG_ERROR(fmt(MSG_WRITING_SERVER_STAT_FILE_FAILED,
|
||||||
|
utf8ToNative(filename).c_str()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(File(tempfile).renameTo(filename)) {
|
||||||
|
A2_LOG_NOTICE(fmt(MSG_SERVER_STAT_SAVED,
|
||||||
|
utf8ToNative(filename).c_str()));
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
A2_LOG_ERROR(fmt(MSG_WRITING_SERVER_STAT_FILE_FAILED,
|
||||||
|
utf8ToNative(filename).c_str()));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
out.flush();
|
|
||||||
return !out.bad();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServerStatMan::load(std::istream& in)
|
bool ServerStatMan::load(const std::string& filename)
|
||||||
{
|
{
|
||||||
static const std::string S_HOST = "host";
|
static const std::string S_HOST = "host";
|
||||||
static const std::string S_PROTOCOL = "protocol";
|
static const std::string S_PROTOCOL = "protocol";
|
||||||
|
@ -101,9 +134,24 @@ bool ServerStatMan::load(std::istream& in)
|
||||||
static const std::string S_COUNTER = "counter";
|
static const std::string S_COUNTER = "counter";
|
||||||
static const std::string S_STATUS = "status";
|
static const std::string S_STATUS = "status";
|
||||||
|
|
||||||
std::string line;
|
BufferedFile fp(filename, BufferedFile::READ);
|
||||||
while(getline(in, line)) {
|
if(!fp) {
|
||||||
line = util::strip(line);
|
A2_LOG_ERROR(fmt(MSG_OPENING_READABLE_SERVER_STAT_FILE_FAILED,
|
||||||
|
utf8ToNative(filename).c_str()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
char buf[4096];
|
||||||
|
while(1) {
|
||||||
|
if(!fp.getsn(buf, sizeof(buf))) {
|
||||||
|
if(fp.eof()) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
A2_LOG_ERROR(fmt(MSG_READING_SERVER_STAT_FILE_FAILED,
|
||||||
|
utf8ToNative(filename).c_str()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string line = util::stripIter(&buf[0], &buf[strlen(buf)]);
|
||||||
if(line.empty()) {
|
if(line.empty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -143,7 +191,8 @@ bool ServerStatMan::load(std::istream& in)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return !in.bad();
|
A2_LOG_NOTICE(fmt(MSG_SERVER_STAT_LOADED, utf8ToNative(filename).c_str()));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <iosfwd>
|
|
||||||
|
|
||||||
#include "SharedHandle.h"
|
#include "SharedHandle.h"
|
||||||
#include "a2time.h"
|
#include "a2time.h"
|
||||||
|
@ -58,9 +57,9 @@ public:
|
||||||
|
|
||||||
bool add(const SharedHandle<ServerStat>& serverStat);
|
bool add(const SharedHandle<ServerStat>& serverStat);
|
||||||
|
|
||||||
bool load(std::istream& in);
|
bool load(const std::string& filename);
|
||||||
|
|
||||||
bool save(std::ostream& out) const;
|
bool save(const std::string& filename) const;
|
||||||
|
|
||||||
void removeStaleServerStat(time_t timeout);
|
void removeStaleServerStat(time_t timeout);
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
#include "ServerStatMan.h"
|
#include "ServerStatMan.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include <cppunit/extensions/HelperMacros.h>
|
#include <cppunit/extensions/HelperMacros.h>
|
||||||
|
|
||||||
#include "ServerStat.h"
|
#include "ServerStat.h"
|
||||||
#include "Exception.h"
|
#include "Exception.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "BufferedFile.h"
|
||||||
|
#include "TestUtil.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -78,9 +79,8 @@ void ServerStatManTest::testSave()
|
||||||
CPPUNIT_ASSERT(ssm.add(localhost_ftp));
|
CPPUNIT_ASSERT(ssm.add(localhost_ftp));
|
||||||
CPPUNIT_ASSERT(ssm.add(mirror));
|
CPPUNIT_ASSERT(ssm.add(mirror));
|
||||||
|
|
||||||
std::stringstream ss;
|
std::string filename = A2_TEST_OUT_DIR"/aria2_ServerStatManTest_testSave";
|
||||||
CPPUNIT_ASSERT(ssm.save(ss));
|
CPPUNIT_ASSERT(ssm.save(filename));
|
||||||
std::string out = ss.str();
|
|
||||||
CPPUNIT_ASSERT_EQUAL
|
CPPUNIT_ASSERT_EQUAL
|
||||||
(std::string
|
(std::string
|
||||||
("host=localhost, protocol=ftp,"
|
("host=localhost, protocol=ftp,"
|
||||||
|
@ -106,20 +106,22 @@ void ServerStatManTest::testSave()
|
||||||
" last_updated=1210000002,"
|
" last_updated=1210000002,"
|
||||||
" counter=0,"
|
" counter=0,"
|
||||||
" status=ERROR\n"),
|
" status=ERROR\n"),
|
||||||
out);
|
readFile(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerStatManTest::testLoad()
|
void ServerStatManTest::testLoad()
|
||||||
{
|
{
|
||||||
|
std::string filename = A2_TEST_OUT_DIR"/aria2_ServerStatManTest_testLoad";
|
||||||
std::string in =
|
std::string in =
|
||||||
"host=localhost, protocol=ftp, dl_speed=30000, last_updated=1210000001, status=OK\n"
|
"host=localhost, protocol=ftp, dl_speed=30000, last_updated=1210000001, status=OK\n"
|
||||||
"host=localhost, protocol=http, dl_speed=25000, sc_avg_speed=101, mc_avg_speed=102, last_updated=1210000000, counter=6, status=OK\n"
|
"host=localhost, protocol=http, dl_speed=25000, sc_avg_speed=101, mc_avg_speed=102, last_updated=1210000000, counter=6, status=OK\n"
|
||||||
"host=mirror, protocol=http, dl_speed=0, last_updated=1210000002, status=ERROR\n";
|
"host=mirror, protocol=http, dl_speed=0, last_updated=1210000002, status=ERROR\n";
|
||||||
|
BufferedFile fp(filename, BufferedFile::WRITE);
|
||||||
std::stringstream ss(in);
|
CPPUNIT_ASSERT_EQUAL((size_t)in.size(), fp.write(in.data(), in.size()));
|
||||||
|
CPPUNIT_ASSERT(fp.close() != EOF);
|
||||||
|
|
||||||
ServerStatMan ssm;
|
ServerStatMan ssm;
|
||||||
CPPUNIT_ASSERT(ssm.load(ss));
|
CPPUNIT_ASSERT(ssm.load(filename));
|
||||||
|
|
||||||
SharedHandle<ServerStat> localhost_http = ssm.find("localhost", "http");
|
SharedHandle<ServerStat> localhost_http = ssm.find("localhost", "http");
|
||||||
CPPUNIT_ASSERT(localhost_http);
|
CPPUNIT_ASSERT(localhost_http);
|
||||||
|
|
|
@ -14,7 +14,7 @@ class ServerStatTest:public CppUnit::TestFixture {
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE(ServerStatTest);
|
CPPUNIT_TEST_SUITE(ServerStatTest);
|
||||||
CPPUNIT_TEST(testSetStatus);
|
CPPUNIT_TEST(testSetStatus);
|
||||||
CPPUNIT_TEST(testOperatorOstream);
|
CPPUNIT_TEST(testToString);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
public:
|
public:
|
||||||
void setUp() {}
|
void setUp() {}
|
||||||
|
@ -22,7 +22,7 @@ public:
|
||||||
void tearDown() {}
|
void tearDown() {}
|
||||||
|
|
||||||
void testSetStatus();
|
void testSetStatus();
|
||||||
void testOperatorOstream();
|
void testToString();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ void ServerStatTest::testSetStatus()
|
||||||
CPPUNIT_ASSERT_EQUAL(ServerStat::OK, ss.getStatus());
|
CPPUNIT_ASSERT_EQUAL(ServerStat::OK, ss.getStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerStatTest::testOperatorOstream()
|
void ServerStatTest::testToString()
|
||||||
{
|
{
|
||||||
ServerStat localhost_http("localhost", "http");
|
ServerStat localhost_http("localhost", "http");
|
||||||
localhost_http.setDownloadSpeed(90000);
|
localhost_http.setDownloadSpeed(90000);
|
||||||
|
@ -53,33 +53,24 @@ void ServerStatTest::testOperatorOstream()
|
||||||
localhost_http.setMultiConnectionAvgSpeed(102);
|
localhost_http.setMultiConnectionAvgSpeed(102);
|
||||||
localhost_http.setCounter(5);
|
localhost_http.setCounter(5);
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
|
|
||||||
ss << localhost_http;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL
|
CPPUNIT_ASSERT_EQUAL
|
||||||
(std::string
|
(std::string
|
||||||
("host=localhost, protocol=http, dl_speed=90000,"
|
("host=localhost, protocol=http, dl_speed=90000,"
|
||||||
" sc_avg_speed=101, mc_avg_speed=102,"
|
" sc_avg_speed=101, mc_avg_speed=102,"
|
||||||
" last_updated=1000, counter=5, status=OK"),
|
" last_updated=1000, counter=5, status=OK"),
|
||||||
ss.str());
|
localhost_http.toString());
|
||||||
|
|
||||||
ss.str("");
|
|
||||||
|
|
||||||
ServerStat localhost_ftp("localhost", "ftp");
|
ServerStat localhost_ftp("localhost", "ftp");
|
||||||
localhost_ftp.setDownloadSpeed(10000);
|
localhost_ftp.setDownloadSpeed(10000);
|
||||||
localhost_ftp.setLastUpdated(Time(1210000000));
|
localhost_ftp.setLastUpdated(Time(1210000000));
|
||||||
localhost_ftp.setStatus("ERROR");
|
localhost_ftp.setStatus("ERROR");
|
||||||
|
|
||||||
ss << localhost_ftp;
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL
|
CPPUNIT_ASSERT_EQUAL
|
||||||
(std::string
|
(std::string
|
||||||
("host=localhost, protocol=ftp, dl_speed=10000,"
|
("host=localhost, protocol=ftp, dl_speed=10000,"
|
||||||
" sc_avg_speed=0, mc_avg_speed=0,"
|
" sc_avg_speed=0, mc_avg_speed=0,"
|
||||||
" last_updated=1210000000, counter=0, status=ERROR"),
|
" last_updated=1210000000, counter=0, status=ERROR"),
|
||||||
ss.str());
|
localhost_ftp.toString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
Loading…
Reference in New Issue