Rewritten ServerStatMan using BufferedFile.

pull/1/head
Tatsuhiro Tsujikawa 2011-08-07 00:10:53 +09:00
parent 7f3d027b83
commit 190d170076
7 changed files with 97 additions and 84 deletions

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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 {

View File

@ -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:

View File

@ -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);

View File

@ -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