fix(LogFile): Unify flushing behaviour of WIN32 and STD implementation (#2443)

This commit is contained in:
Matej Kenda 2024-01-31 11:41:20 +01:00
parent db5a8a7112
commit eb51c78305
4 changed files with 72 additions and 5 deletions

View File

@ -16,6 +16,7 @@
#include "Poco/File.h"
#include "Poco/Exception.h"
#include <unistd.h>
namespace Poco {
@ -40,17 +41,26 @@ LogFileImpl::~LogFileImpl()
void LogFileImpl::writeImpl(const std::string& text, bool flush)
{
std::streampos pos = _str.tellp();
_str << text;
if (flush)
_str << std::endl;
else
_str << "\n";
_str << text << '\n';
// Flush the stream buffer to file to match the implementation on Windows
_str.flush();
if (!_str.good())
{
_str.clear();
_str.seekp(pos);
throw WriteFileException(_path);
}
if (flush)
{
// Sync the file to disk as it is done on Windows
if (fsync(_str.nativeHandle()) != 0)
throw WriteFileException(_path);
}
_size = static_cast<UInt64>(_str.tellp());
}

View File

@ -17,6 +17,8 @@
#include "Poco/Exception.h"
#include "Poco/UnicodeConverter.h"
// TODO: LogStream shall use FileOutputStream for all implementations (see LogStream_STD)
// TODO: Implement flushToDisk function in FileOutputStream.
namespace Poco {

View File

@ -86,6 +86,59 @@ void FileChannelTest::testRotateNever()
}
void FileChannelTest::testFlushing()
{
std::string name = filename();
try
{
AutoPtr<FileChannel> pChannel = new FileChannel(name);
pChannel->setProperty(FileChannel::PROP_FLUSH, "false");
pChannel->open();
Message msg("source", "01234567890123456789", Message::PRIO_INFORMATION);
pChannel->log(msg);
// File shall be there and have content after writing first message.
File f(name);
assertTrue (f.exists());
assertTrue (f.getSize() >= 20);
Timestamp::TimeDiff noFlushTime;
{
Timestamp start;
for (int i = 0; i < 2000; ++i)
{
pChannel->log(msg);
}
pChannel->close();
Timestamp end;
noFlushTime = end-start;
}
Timestamp::TimeDiff flushTime;
{
pChannel->setProperty(FileChannel::PROP_FLUSH, "true");
pChannel->open();
Timestamp start;
for (int i = 0; i < 2000; ++i)
{
pChannel->log(msg);
}
pChannel->close();
Timestamp end;
flushTime = end-start;
}
// Writing to channel with flushing is expected to be slower.
assertTrue(flushTime > noFlushTime);
}
catch (...)
{
remove(name);
throw;
}
remove(name);
}
void FileChannelTest::testRotateBySize()
{
std::string name = filename();
@ -832,6 +885,7 @@ CppUnit::Test* FileChannelTest::suite()
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("FileChannelTest");
CppUnit_addTest(pSuite, FileChannelTest, testRotateNever);
CppUnit_addTest(pSuite, FileChannelTest, testFlushing);
CppUnit_addTest(pSuite, FileChannelTest, testRotateBySize);
CppUnit_addTest(pSuite, FileChannelTest, testRotateByAge);
CppUnit_addLongTest(pSuite, FileChannelTest, testRotateAtTimeDayUTC);

View File

@ -32,6 +32,7 @@ public:
~FileChannelTest();
void testRotateNever();
void testFlushing();
void testRotateBySize();
void testRotateByAge();
void testRotateAtTimeDayUTC();