Auto reformatted the base, ref #470
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include <cassert>
|
||||
#include <cstring> // strerror
|
||||
#include <fstream>
|
||||
|
||||
#include <archive.h>
|
||||
#include <archive_entry.h>
|
||||
|
||||
@@ -39,12 +40,14 @@ namespace lms::zip
|
||||
{
|
||||
public:
|
||||
FileException(const std::filesystem::path& p, std::string_view message)
|
||||
: Exception{ "File '" + p.string() + "': " + std::string {message} }
|
||||
{}
|
||||
: Exception{ "File '" + p.string() + "': " + std::string{ message } }
|
||||
{
|
||||
}
|
||||
|
||||
FileException(const std::filesystem::path& p, std::string_view message, int err)
|
||||
: Exception{ "File '" + p.string() + "': " + std::string {message} + ": " + ::strerror(err) }
|
||||
{}
|
||||
: Exception{ "File '" + p.string() + "': " + std::string{ message } + ": " + ::strerror(err) }
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class ArchiveException : public Exception
|
||||
@@ -52,7 +55,8 @@ namespace lms::zip
|
||||
public:
|
||||
ArchiveException(struct ::archive* arch)
|
||||
: Exception{ getError(arch) }
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
static std::string_view getError(struct ::archive* arch)
|
||||
{
|
||||
@@ -88,19 +92,16 @@ namespace lms::zip
|
||||
if (!_archive)
|
||||
throw Exception{ "Cannot create archive control struct" };
|
||||
|
||||
auto archiveOpen{ [](struct ::archive*, void*)
|
||||
{
|
||||
auto archiveOpen{ [](struct ::archive*, void*) {
|
||||
return ARCHIVE_OK;
|
||||
} };
|
||||
|
||||
auto archiveWrite{ [](struct ::archive*, void* clientData, const void* buff, ::size_t n) -> la_ssize_t
|
||||
{
|
||||
ArchiveZipper* zipper {static_cast<ArchiveZipper*>(clientData)};
|
||||
auto archiveWrite{ [](struct ::archive*, void* clientData, const void* buff, ::size_t n) -> la_ssize_t {
|
||||
ArchiveZipper* zipper{ static_cast<ArchiveZipper*>(clientData) };
|
||||
return zipper->onWriteCallback(static_cast<const std::byte*>(buff), n);
|
||||
} };
|
||||
|
||||
auto archiveClose{ [](struct ::archive*, void*)
|
||||
{
|
||||
auto archiveClose{ [](struct ::archive*, void*) {
|
||||
return ARCHIVE_OK;
|
||||
} };
|
||||
|
||||
@@ -183,8 +184,7 @@ namespace lms::zip
|
||||
using std::filesystem::perms;
|
||||
::mode_t mode{};
|
||||
|
||||
auto testPerm{ [](perms p, perms permToTest)
|
||||
{
|
||||
auto testPerm{ [](perms p, perms permToTest) {
|
||||
return (p & permToTest) == permToTest;
|
||||
} };
|
||||
|
||||
@@ -295,4 +295,4 @@ namespace lms::zip
|
||||
|
||||
return bufferSize;
|
||||
}
|
||||
}
|
||||
} // namespace lms::zip
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
|
||||
#include "core/IZipper.hpp"
|
||||
|
||||
extern "C"
|
||||
@@ -77,4 +78,4 @@ namespace lms::zip
|
||||
std::uint64_t _bytesWrittenInCurrentOutputStream{};
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace lms::zip
|
||||
@@ -19,21 +19,21 @@
|
||||
|
||||
#include "ChildProcess.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdexcept>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
|
||||
#include <boost/asio/read.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/read.hpp>
|
||||
|
||||
#include "core/Exception.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
@@ -47,13 +47,15 @@ namespace lms::core
|
||||
public:
|
||||
SystemException(int err, const std::string& errMsg)
|
||||
: ChildProcessException{ errMsg + ": " + ::strerror(err) }
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
SystemException(boost::system::error_code ec, const std::string& errMsg)
|
||||
: ChildProcessException{ errMsg + ": " + ec.message() }
|
||||
{}
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
ChildProcess::ChildProcess(boost::asio::io_context& ioContext, const std::filesystem::path& path, const Args& args)
|
||||
: _ioContext{ ioContext }
|
||||
@@ -170,8 +172,7 @@ namespace lms::core
|
||||
LMS_LOG(CHILDPROCESS, DEBUG, "Async read, bufferSize = " << bufferSize);
|
||||
|
||||
boost::asio::async_read(_childStdout, boost::asio::buffer(data, bufferSize),
|
||||
[this, callback{ std::move(callback) }](const boost::system::error_code& error, std::size_t bytesTransferred)
|
||||
{
|
||||
[this, callback{ std::move(callback) }](const boost::system::error_code& error, std::size_t bytesTransferred) {
|
||||
LMS_LOG(CHILDPROCESS, DEBUG, "Async read cb - ec = '" << error.message() << "' (" << error.value() << "), bytesTransferred = " << bytesTransferred);
|
||||
|
||||
ReadResult readResult{ ReadResult::Success };
|
||||
@@ -206,4 +207,4 @@ namespace lms::core
|
||||
{
|
||||
return _finished;
|
||||
}
|
||||
}
|
||||
} // namespace lms::core
|
||||
@@ -40,20 +40,20 @@ namespace lms::core
|
||||
ChildProcess(boost::asio::io_context& ioContext, const std::filesystem::path& path, const Args& args);
|
||||
|
||||
private:
|
||||
void asyncRead(std::byte* data, std::size_t bufferSize, ReadCallback callback) override;
|
||||
std::size_t readSome(std::byte* data, std::size_t bufferSize) override;
|
||||
bool finished() const override;
|
||||
void asyncRead(std::byte* data, std::size_t bufferSize, ReadCallback callback) override;
|
||||
std::size_t readSome(std::byte* data, std::size_t bufferSize) override;
|
||||
bool finished() const override;
|
||||
|
||||
void kill();
|
||||
bool wait(bool block); // return true if waited
|
||||
void kill();
|
||||
bool wait(bool block); // return true if waited
|
||||
|
||||
using FileDescriptor = boost::asio::posix::stream_descriptor;
|
||||
|
||||
boost::asio::io_context& _ioContext;
|
||||
FileDescriptor _childStdout;
|
||||
::pid_t _childPID{};
|
||||
bool _waited{};
|
||||
bool _finished{};
|
||||
std::optional<int> _exitCode;
|
||||
FileDescriptor _childStdout;
|
||||
::pid_t _childPID{};
|
||||
bool _waited{};
|
||||
bool _finished{};
|
||||
std::optional<int> _exitCode;
|
||||
};
|
||||
}
|
||||
} // namespace lms::core
|
||||
@@ -39,4 +39,4 @@ namespace lms::core
|
||||
{
|
||||
return std::make_unique<ChildProcess>(_ioContext, path, args);
|
||||
}
|
||||
}
|
||||
} // namespace lms::core
|
||||
@@ -44,4 +44,4 @@ namespace lms::core
|
||||
|
||||
boost::asio::io_context& _ioContext;
|
||||
};
|
||||
}
|
||||
} // namespace lms::core
|
||||
@@ -65,7 +65,7 @@ namespace lms::core
|
||||
{
|
||||
try
|
||||
{
|
||||
const libconfig::Setting& values{ _config.lookup(std::string {setting}) };
|
||||
const libconfig::Setting& values{ _config.lookup(std::string{ setting }) };
|
||||
for (int i{}; i < values.getLength(); ++i)
|
||||
_func(static_cast<const char*>(values[i]));
|
||||
}
|
||||
@@ -83,7 +83,7 @@ namespace lms::core
|
||||
{
|
||||
try
|
||||
{
|
||||
const char* res{ _config.lookup(std::string {setting}) };
|
||||
const char* res{ _config.lookup(std::string{ setting }) };
|
||||
return std::filesystem::path{ std::string(res) };
|
||||
}
|
||||
catch (libconfig::ConfigException&)
|
||||
@@ -127,4 +127,4 @@ namespace lms::core
|
||||
return def;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace lms::core
|
||||
@@ -37,15 +37,14 @@ namespace lms::core
|
||||
Config& operator=(Config&&) = delete;
|
||||
|
||||
// Default values are returned in case of setting not found
|
||||
std::string_view getString(std::string_view setting, std::string_view def = "") override;
|
||||
void visitStrings(std::string_view setting, std::function<void(std::string_view)> _func, std::initializer_list<std::string_view> defs) override;
|
||||
std::filesystem::path getPath(std::string_view setting, const std::filesystem::path& def = std::filesystem::path()) override;
|
||||
unsigned long getULong(std::string_view setting, unsigned long def = 0) override;
|
||||
long getLong(std::string_view setting, long def = 0) override;
|
||||
bool getBool(std::string_view setting, bool def = false) override;
|
||||
std::string_view getString(std::string_view setting, std::string_view def = "") override;
|
||||
void visitStrings(std::string_view setting, std::function<void(std::string_view)> _func, std::initializer_list<std::string_view> defs) override;
|
||||
std::filesystem::path getPath(std::string_view setting, const std::filesystem::path& def = std::filesystem::path()) override;
|
||||
unsigned long getULong(std::string_view setting, unsigned long def = 0) override;
|
||||
long getLong(std::string_view setting, long def = 0) override;
|
||||
bool getBool(std::string_view setting, bool def = false) override;
|
||||
|
||||
private:
|
||||
|
||||
libconfig::Config _config;
|
||||
};
|
||||
}
|
||||
} // namespace lms::core
|
||||
@@ -80,7 +80,7 @@ namespace lms
|
||||
|
||||
std::ostringstream contentRange;
|
||||
contentRange << "bytes " << startByte << "-"
|
||||
<< _beyondLastByte - 1 << "/" << fileSize;
|
||||
<< _beyondLastByte - 1 << "/" << fileSize;
|
||||
|
||||
response.addHeader("Content-Range", contentRange.str());
|
||||
response.setContentLength(_beyondLastByte - startByte);
|
||||
@@ -134,4 +134,4 @@ namespace lms
|
||||
LMS_LOG(UTILS, DEBUG, "Job complete!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
} // namespace lms
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "core/IResourceHandler.hpp"
|
||||
|
||||
namespace lms
|
||||
@@ -33,13 +34,13 @@ namespace lms
|
||||
|
||||
private:
|
||||
Wt::Http::ResponseContinuation* processRequest(const Wt::Http::Request& request, Wt::Http::Response& response) override;
|
||||
void abort() override {};
|
||||
void abort() override{};
|
||||
|
||||
static constexpr std::size_t _chunkSize{ 262'144 };
|
||||
|
||||
std::filesystem::path _path;
|
||||
std::string _mimeType;
|
||||
::uint64_t _beyondLastByte{};
|
||||
::uint64_t _offset{};
|
||||
std::filesystem::path _path;
|
||||
std::string _mimeType;
|
||||
::uint64_t _beyondLastByte{};
|
||||
::uint64_t _offset{};
|
||||
};
|
||||
}
|
||||
} // namespace lms
|
||||
@@ -41,24 +41,23 @@ namespace lms::core
|
||||
threadName += std::to_string(i);
|
||||
}
|
||||
|
||||
_threads.emplace_back([this, threadName]
|
||||
_threads.emplace_back([this, threadName] {
|
||||
if (!threadName.empty())
|
||||
{
|
||||
if (!threadName.empty())
|
||||
{
|
||||
if (auto * traceLogger{ Service<tracing::ITraceLogger>::get() })
|
||||
traceLogger->setThreadName(std::this_thread::get_id(), threadName);
|
||||
}
|
||||
if (auto* traceLogger{ Service<tracing::ITraceLogger>::get() })
|
||||
traceLogger->setThreadName(std::this_thread::get_id(), threadName);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_ioService.run();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LMS_LOG(UTILS, FATAL, "Exception caught in IO context: " << e.what());
|
||||
std::abort();
|
||||
}
|
||||
});
|
||||
try
|
||||
{
|
||||
_ioService.run();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LMS_LOG(UTILS, FATAL, "Exception caught in IO context: " << e.what());
|
||||
std::abort();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,4 +81,4 @@ namespace lms::core
|
||||
for (std::thread& t : _threads)
|
||||
t.join();
|
||||
}
|
||||
}
|
||||
} // namespace lms::core
|
||||
@@ -25,25 +25,44 @@ namespace lms::core::logging
|
||||
{
|
||||
switch (mod)
|
||||
{
|
||||
case Module::API_SUBSONIC: return "API_SUBSONIC";
|
||||
case Module::AUTH: return "AUTH";
|
||||
case Module::AV: return "AV";
|
||||
case Module::CHILDPROCESS: return "CHILDPROC";
|
||||
case Module::COVER: return "COVER";
|
||||
case Module::DB: return "DB";
|
||||
case Module::DBUPDATER: return "DB UPDATER";
|
||||
case Module::FEATURE: return "FEATURE";
|
||||
case Module::FEEDBACK: return "FEEDBACK";
|
||||
case Module::HTTP: return "HTTP";
|
||||
case Module::MAIN: return "MAIN";
|
||||
case Module::METADATA: return "METADATA";
|
||||
case Module::REMOTE: return "REMOTE";
|
||||
case Module::SCROBBLING: return "SCROBBLING";
|
||||
case Module::SERVICE: return "SERVICE";
|
||||
case Module::RECOMMENDATION: return "RECOMMENDATION";
|
||||
case Module::TRANSCODING: return "TRANSCODING";
|
||||
case Module::UI: return "UI";
|
||||
case Module::UTILS: return "UTILS";
|
||||
case Module::API_SUBSONIC:
|
||||
return "API_SUBSONIC";
|
||||
case Module::AUTH:
|
||||
return "AUTH";
|
||||
case Module::AV:
|
||||
return "AV";
|
||||
case Module::CHILDPROCESS:
|
||||
return "CHILDPROC";
|
||||
case Module::COVER:
|
||||
return "COVER";
|
||||
case Module::DB:
|
||||
return "DB";
|
||||
case Module::DBUPDATER:
|
||||
return "DB UPDATER";
|
||||
case Module::FEATURE:
|
||||
return "FEATURE";
|
||||
case Module::FEEDBACK:
|
||||
return "FEEDBACK";
|
||||
case Module::HTTP:
|
||||
return "HTTP";
|
||||
case Module::MAIN:
|
||||
return "MAIN";
|
||||
case Module::METADATA:
|
||||
return "METADATA";
|
||||
case Module::REMOTE:
|
||||
return "REMOTE";
|
||||
case Module::SCROBBLING:
|
||||
return "SCROBBLING";
|
||||
case Module::SERVICE:
|
||||
return "SERVICE";
|
||||
case Module::RECOMMENDATION:
|
||||
return "RECOMMENDATION";
|
||||
case Module::TRANSCODING:
|
||||
return "TRANSCODING";
|
||||
case Module::UI:
|
||||
return "UI";
|
||||
case Module::UTILS:
|
||||
return "UTILS";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -52,11 +71,16 @@ namespace lms::core::logging
|
||||
{
|
||||
switch (sev)
|
||||
{
|
||||
case Severity::FATAL: return "fatal";
|
||||
case Severity::ERROR: return "error";
|
||||
case Severity::WARNING: return "warning";
|
||||
case Severity::INFO: return "info";
|
||||
case Severity::DEBUG: return "debug";
|
||||
case Severity::FATAL:
|
||||
return "fatal";
|
||||
case Severity::ERROR:
|
||||
return "error";
|
||||
case Severity::WARNING:
|
||||
return "warning";
|
||||
case Severity::INFO:
|
||||
return "info";
|
||||
case Severity::DEBUG:
|
||||
return "debug";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -66,7 +90,8 @@ namespace lms::core::logging
|
||||
, _module{ module }
|
||||
, _severity{ severity }
|
||||
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
Log::~Log()
|
||||
{
|
||||
@@ -78,4 +103,4 @@ namespace lms::core::logging
|
||||
{
|
||||
return _oss.str();
|
||||
}
|
||||
}
|
||||
} // namespace lms::core::logging
|
||||
@@ -23,24 +23,24 @@
|
||||
|
||||
namespace std
|
||||
{
|
||||
std::size_t hash<boost::asio::ip::address>::operator()(const boost::asio::ip::address& ipAddr) const
|
||||
{
|
||||
if (ipAddr.is_v4())
|
||||
return ipAddr.to_v4().to_ulong();
|
||||
std::size_t hash<boost::asio::ip::address>::operator()(const boost::asio::ip::address& ipAddr) const
|
||||
{
|
||||
if (ipAddr.is_v4())
|
||||
return ipAddr.to_v4().to_ulong();
|
||||
|
||||
if (ipAddr.is_v6())
|
||||
{
|
||||
const auto& range {ipAddr.to_v6().to_bytes()};
|
||||
std::size_t res {};
|
||||
if (ipAddr.is_v6())
|
||||
{
|
||||
const auto& range{ ipAddr.to_v6().to_bytes() };
|
||||
std::size_t res{};
|
||||
|
||||
for (auto b : range)
|
||||
res ^= std::hash<char>{}(static_cast<char>(b));
|
||||
for (auto b : range)
|
||||
res ^= std::hash<char>{}(static_cast<char>(b));
|
||||
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
return std::hash<std::string>{}(ipAddr.to_string());
|
||||
}
|
||||
}
|
||||
return std::hash<std::string>{}(ipAddr.to_string());
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
#endif // BOOST_ASIO_HAS_STD_HASH
|
||||
|
||||
@@ -19,12 +19,11 @@
|
||||
|
||||
#include "core/Path.hpp"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <boost/tokenizer.hpp>
|
||||
|
||||
@@ -44,7 +43,7 @@ namespace lms::core::pathUtils
|
||||
{
|
||||
do
|
||||
{
|
||||
std::array<char, 1024> buffer;
|
||||
std::array<char, 1024> buffer;
|
||||
|
||||
ifs.read(buffer.data(), buffer.size());
|
||||
crc32.processBytes(reinterpret_cast<const std::byte*>(buffer.data()), ifs.gcount());
|
||||
@@ -69,7 +68,9 @@ namespace lms::core::pathUtils
|
||||
|
||||
Wt::WDateTime getLastWriteTime(const std::filesystem::path& file)
|
||||
{
|
||||
struct stat sb {};
|
||||
struct stat sb
|
||||
{
|
||||
};
|
||||
|
||||
if (stat(file.string().c_str(), &sb) == -1)
|
||||
throw LmsException("Failed to get stats on file '" + file.string() + "'");
|
||||
@@ -183,4 +184,4 @@ namespace lms::core::pathUtils
|
||||
|
||||
return longestCommonPath;
|
||||
}
|
||||
}
|
||||
} // namespace lms::core::pathUtils
|
||||
|
||||
@@ -35,4 +35,4 @@ namespace lms::core::random
|
||||
return RandGenerator{ seed };
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace lms::core::random
|
||||
@@ -131,4 +131,4 @@ namespace lms::core
|
||||
return _sharedCounts[thisThreadId] > 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} // namespace lms::core
|
||||
@@ -35,4 +35,4 @@ namespace lms::core::logging
|
||||
assert(isSeverityActive(log.getSeverity()));
|
||||
_os << std::this_thread::get_id() << " [" << getSeverityName(log.getSeverity()) << "] [" << getModuleName(log.getModule()) << "] " << log.getMessage() << std::endl;
|
||||
}
|
||||
}
|
||||
} // namespace lms::core::logging
|
||||
@@ -23,15 +23,14 @@
|
||||
#include <iomanip>
|
||||
#include <utility>
|
||||
|
||||
#include <Wt/WDateTime.h>
|
||||
#include <Wt/WDate.h>
|
||||
#include <Wt/WDateTime.h>
|
||||
|
||||
namespace lms::core::stringUtils
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
constexpr std::pair<char, std::string_view> jsEscapeChars[]
|
||||
{
|
||||
constexpr std::pair<char, std::string_view> jsEscapeChars[]{
|
||||
{ '\\', "\\\\" },
|
||||
{ '\n', "\\n" },
|
||||
{ '\r', "\\r" },
|
||||
@@ -40,8 +39,7 @@ namespace lms::core::stringUtils
|
||||
{ '\'', "\\\'" },
|
||||
};
|
||||
|
||||
constexpr std::pair<char, std::string_view> jsonEscapeChars[]
|
||||
{
|
||||
constexpr std::pair<char, std::string_view> jsonEscapeChars[]{
|
||||
{ '\\', "\\\\" },
|
||||
{ '\n', "\\n" },
|
||||
{ '\r', "\\r" },
|
||||
@@ -49,8 +47,8 @@ namespace lms::core::stringUtils
|
||||
{ '"', "\\\"" },
|
||||
};
|
||||
|
||||
template <std::size_t N>
|
||||
std::string escape(std::string_view str, const std::pair<char, std::string_view>(&charsToEscape)[N])
|
||||
template<std::size_t N>
|
||||
std::string escape(std::string_view str, const std::pair<char, std::string_view> (&charsToEscape)[N])
|
||||
{
|
||||
std::string escaped;
|
||||
escaped.reserve(str.length());
|
||||
@@ -70,12 +68,12 @@ namespace lms::core::stringUtils
|
||||
return escaped;
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
void writeEscapedString(std::ostream& os, std::string_view str, const std::pair<char, std::string_view>(&charsToEscape)[N])
|
||||
template<std::size_t N>
|
||||
void writeEscapedString(std::ostream& os, std::string_view str, const std::pair<char, std::string_view> (&charsToEscape)[N])
|
||||
{
|
||||
for (const char c : str)
|
||||
{
|
||||
auto itEntry{ std::find_if(std::cbegin(charsToEscape), std::cend(charsToEscape), [=](const auto& entry) { return entry.first == c;}) };
|
||||
auto itEntry{ std::find_if(std::cbegin(charsToEscape), std::cend(charsToEscape), [=](const auto& entry) { return entry.first == c; }) };
|
||||
if (itEntry != std::cend(charsToEscape))
|
||||
os << itEntry->second;
|
||||
else
|
||||
@@ -83,7 +81,7 @@ namespace lms::core::stringUtils
|
||||
}
|
||||
}
|
||||
|
||||
template <typename StringType>
|
||||
template<typename StringType>
|
||||
std::string joinStrings(std::span<const StringType> strings, std::string_view delimiter)
|
||||
{
|
||||
std::string res;
|
||||
@@ -99,7 +97,7 @@ namespace lms::core::stringUtils
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
} // namespace details
|
||||
|
||||
template<>
|
||||
std::optional<std::string> readAs(std::string_view str)
|
||||
@@ -198,7 +196,8 @@ namespace lms::core::stringUtils
|
||||
|
||||
for (char c : str)
|
||||
{
|
||||
if (escaped) {
|
||||
if (escaped)
|
||||
{
|
||||
current.push_back(c);
|
||||
escaped = false;
|
||||
}
|
||||
@@ -248,14 +247,14 @@ namespace lms::core::stringUtils
|
||||
std::string res;
|
||||
res.reserve(str.size());
|
||||
|
||||
std::transform(std::cbegin(str), std::cend(str), std::back_inserter(res), [](unsigned char c) { return std::tolower(c);});
|
||||
std::transform(std::cbegin(str), std::cend(str), std::back_inserter(res), [](unsigned char c) { return std::tolower(c); });
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void stringToLower(std::string& str)
|
||||
{
|
||||
std::transform(std::cbegin(str), std::cend(str), std::begin(str), [](unsigned char c) { return std::tolower(c);});
|
||||
std::transform(std::cbegin(str), std::cend(str), std::begin(str), [](unsigned char c) { return std::tolower(c); });
|
||||
}
|
||||
|
||||
std::string stringToUpper(const std::string& str)
|
||||
@@ -263,7 +262,7 @@ namespace lms::core::stringUtils
|
||||
std::string res;
|
||||
res.reserve(str.size());
|
||||
|
||||
std::transform(std::cbegin(str), std::cend(str), std::back_inserter(res), [](char c) { return std::toupper(c);});
|
||||
std::transform(std::cbegin(str), std::cend(str), std::back_inserter(res), [](char c) { return std::toupper(c); });
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -436,4 +435,4 @@ namespace lms::core::stringUtils
|
||||
// assume UTC
|
||||
return date.toString("yyyy-MM-dd").toUTF8();
|
||||
}
|
||||
}
|
||||
} // namespace lms::core::stringUtils
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "core/Exception.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
|
||||
@@ -32,7 +33,8 @@ namespace lms::core::tracing
|
||||
class CurrentThreadUnregisterer
|
||||
{
|
||||
public:
|
||||
CurrentThreadUnregisterer(TraceLogger* logger) : _logger{ logger } {}
|
||||
CurrentThreadUnregisterer(TraceLogger* logger)
|
||||
: _logger{ logger } {}
|
||||
~CurrentThreadUnregisterer()
|
||||
{
|
||||
if (_logger)
|
||||
@@ -45,7 +47,7 @@ namespace lms::core::tracing
|
||||
|
||||
TraceLogger* _logger;
|
||||
};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
thread_local TraceLogger::Buffer* TraceLogger::_currentBuffer{};
|
||||
|
||||
@@ -71,11 +73,11 @@ namespace lms::core::tracing
|
||||
LMS_LOG(UTILS, INFO, "TraceLogger: using " << _buffers.size() << " buffers. Buffer size = " << std::to_string(BufferSize) << ", entry size = " << sizeof(CompleteEventEntry) << ", entry count per buffer = " << Buffer::CompleteEventCount);
|
||||
|
||||
setMetadata("cpu_count", std::to_string(std::thread::hardware_concurrency()));
|
||||
setMetadata("build_type",
|
||||
setMetadata("build_type",
|
||||
#ifndef NDEBUG
|
||||
"debug"
|
||||
"debug"
|
||||
#else
|
||||
"release"
|
||||
"release"
|
||||
#endif
|
||||
);
|
||||
}
|
||||
@@ -182,7 +184,8 @@ namespace lms::core::tracing
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
os << ", " << std::endl;;
|
||||
os << ", " << std::endl;
|
||||
;
|
||||
|
||||
os << "\t\t{ ";
|
||||
os << "\"name\" : \"" << event.name << "\", ";
|
||||
@@ -297,4 +300,4 @@ namespace lms::core::tracing
|
||||
|
||||
return static_cast<std::uint32_t>(id);
|
||||
}
|
||||
}
|
||||
} // namespace lms::core::tracing
|
||||
@@ -103,4 +103,4 @@ namespace lms::core::tracing
|
||||
|
||||
static thread_local Buffer* _currentBuffer;
|
||||
};
|
||||
}
|
||||
} // namespace lms::core::tracing
|
||||
@@ -31,13 +31,13 @@ namespace lms::core
|
||||
{
|
||||
namespace stringUtils
|
||||
{
|
||||
template <>
|
||||
template<>
|
||||
std::optional<UUID>
|
||||
readAs(std::string_view str)
|
||||
readAs(std::string_view str)
|
||||
{
|
||||
return UUID::fromString(str);
|
||||
}
|
||||
}
|
||||
} // namespace stringUtils
|
||||
namespace
|
||||
{
|
||||
bool stringIsUUID(std::string_view str)
|
||||
@@ -46,7 +46,7 @@ namespace lms::core
|
||||
|
||||
return std::regex_match(std::cbegin(str), std::cend(str), re);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
UUID::UUID(std::string_view str)
|
||||
: _value{ stringUtils::stringToLower(str) }
|
||||
@@ -68,9 +68,8 @@ namespace lms::core
|
||||
|
||||
std::ostringstream oss;
|
||||
|
||||
auto concatRandomBytes{ [](std::ostream& os, std::size_t byteCount)
|
||||
{
|
||||
for (std::size_t i {}; i < byteCount; ++i)
|
||||
auto concatRandomBytes{ [](std::ostream& os, std::size_t byteCount) {
|
||||
for (std::size_t i{}; i < byteCount; ++i)
|
||||
os << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(random::getRandom<std::uint8_t>(0, 255));
|
||||
} };
|
||||
|
||||
@@ -88,4 +87,4 @@ namespace lms::core
|
||||
assert(uuid);
|
||||
return uuid.value();
|
||||
}
|
||||
}
|
||||
} // namespace lms::core
|
||||
@@ -19,10 +19,11 @@
|
||||
|
||||
#include "core/WtLogger.hpp"
|
||||
|
||||
#include <thread>
|
||||
#include <sstream>
|
||||
#include <Wt/WServer.h>
|
||||
#include <thread>
|
||||
|
||||
#include <Wt/WLogger.h>
|
||||
#include <Wt/WServer.h>
|
||||
|
||||
#include "core/Exception.hpp"
|
||||
|
||||
@@ -36,7 +37,7 @@ namespace lms::core::logging
|
||||
oss << id;
|
||||
return oss.str();
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
WtLogger::WtLogger(Severity minSeverity)
|
||||
: _minSeverity{ minSeverity }
|
||||
@@ -47,11 +48,16 @@ namespace lms::core::logging
|
||||
{
|
||||
switch (minSeverity)
|
||||
{
|
||||
case Severity::DEBUG: return "*";
|
||||
case Severity::INFO: return "* -debug";
|
||||
case Severity::WARNING: return "* -debug -info";
|
||||
case Severity::ERROR: return "* -debug -info -warning";
|
||||
case Severity::FATAL: return "* -debug -info -warning -error";
|
||||
case Severity::DEBUG:
|
||||
return "*";
|
||||
case Severity::INFO:
|
||||
return "* -debug";
|
||||
case Severity::WARNING:
|
||||
return "* -debug -info";
|
||||
case Severity::ERROR:
|
||||
return "* -debug -info -warning";
|
||||
case Severity::FATAL:
|
||||
return "* -debug -info -warning -error";
|
||||
}
|
||||
|
||||
throw LmsException{ "Unhandled severity" };
|
||||
@@ -66,4 +72,4 @@ namespace lms::core::logging
|
||||
{
|
||||
Wt::log(getSeverityName(log.getSeverity())) << Wt::WLogger::sep << to_string(std::this_thread::get_id()) << Wt::WLogger::sep << "[" << getModuleName(log.getModule()) << "]" << Wt::WLogger::sep << log.getMessage();
|
||||
}
|
||||
}
|
||||
} // namespace lms::core::logging
|
||||
@@ -36,4 +36,4 @@ namespace lms::core::http
|
||||
{
|
||||
_sendQueue.sendRequest(std::make_unique<ClientRequest>(std::move(POSTParams)));
|
||||
}
|
||||
}
|
||||
} // namespace lms::core::http
|
||||
@@ -19,11 +19,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <shared_mutex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "core/http/IClient.hpp"
|
||||
|
||||
#include "SendQueue.hpp"
|
||||
|
||||
namespace lms::core::http
|
||||
@@ -33,7 +34,8 @@ namespace lms::core::http
|
||||
public:
|
||||
Client(boost::asio::io_context& ioContext, std::string_view baseUrl)
|
||||
: _sendQueue{ ioContext, baseUrl }
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
void sendGETRequest(ClientGETRequestParameters&& request) override;
|
||||
@@ -41,4 +43,4 @@ namespace lms::core::http
|
||||
|
||||
SendQueue _sendQueue;
|
||||
};
|
||||
}
|
||||
} // namespace lms::core::http
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <variant>
|
||||
|
||||
#include "core/http/ClientRequestParameters.hpp"
|
||||
|
||||
namespace lms::core::http
|
||||
@@ -28,8 +29,10 @@ namespace lms::core::http
|
||||
class ClientRequest
|
||||
{
|
||||
public:
|
||||
ClientRequest(ClientGETRequestParameters&& GETParams) : _parameters{ std::move(GETParams) } {}
|
||||
ClientRequest(ClientPOSTRequestParameters&& POSTParams) : _parameters{ std::move(POSTParams) } {}
|
||||
ClientRequest(ClientGETRequestParameters&& GETParams)
|
||||
: _parameters{ std::move(GETParams) } {}
|
||||
ClientRequest(ClientPOSTRequestParameters&& POSTParams)
|
||||
: _parameters{ std::move(POSTParams) } {}
|
||||
|
||||
std::size_t retryCount{};
|
||||
|
||||
@@ -37,10 +40,10 @@ namespace lms::core::http
|
||||
{
|
||||
const ClientRequestParameters* res;
|
||||
|
||||
std::visit([&](const auto& parameters)
|
||||
{
|
||||
res = &static_cast<const ClientRequestParameters&>(parameters);
|
||||
}, _parameters);
|
||||
std::visit([&](const auto& parameters) {
|
||||
res = &static_cast<const ClientRequestParameters&>(parameters);
|
||||
},
|
||||
_parameters);
|
||||
|
||||
return *res;
|
||||
}
|
||||
@@ -71,4 +74,4 @@ namespace lms::core::http
|
||||
private:
|
||||
std::variant<ClientGETRequestParameters, ClientPOSTRequestParameters> _parameters;
|
||||
};
|
||||
}
|
||||
} // namespace lms::core::http
|
||||
|
||||
@@ -19,15 +19,15 @@
|
||||
|
||||
#include "SendQueue.hpp"
|
||||
|
||||
#include <boost/asio/dispatch.hpp>
|
||||
#include <boost/asio/bind_executor.hpp>
|
||||
#include <boost/asio/dispatch.hpp>
|
||||
|
||||
#include "core/Exception.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
#include "core/ITraceLogger.hpp"
|
||||
#include "core/String.hpp"
|
||||
|
||||
#define LOG(sev, message) LMS_LOG(SCROBBLING, sev, "[Http SendQueue] - " << message)
|
||||
#define LOG(sev, message) LMS_LOG(SCROBBLING, sev, "[Http SendQueue] - " << message)
|
||||
|
||||
namespace lms::core::stringUtils
|
||||
{
|
||||
@@ -41,35 +41,33 @@ namespace lms::core::stringUtils
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
} // namespace lms::core::stringUtils
|
||||
|
||||
namespace lms::core::http
|
||||
{
|
||||
namespace
|
||||
{
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
std::optional<T> headerReadAs(const Wt::Http::Message& msg, std::string_view headerName)
|
||||
{
|
||||
std::optional<T> res;
|
||||
|
||||
if (const std::string * headerValue{ msg.getHeader(std::string {headerName}) })
|
||||
if (const std::string * headerValue{ msg.getHeader(std::string{ headerName }) })
|
||||
res = stringUtils::readAs<T>(*headerValue);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
SendQueue::SendQueue(boost::asio::io_context& ioContext, std::string_view baseUrl)
|
||||
: _ioContext{ ioContext }
|
||||
, _baseUrl{ baseUrl }
|
||||
{
|
||||
_client.done().connect([this](Wt::AsioWrapper::error_code ec, const Wt::Http::Message& msg)
|
||||
{
|
||||
_strand.dispatch([this, ec, msg = std::move(msg)]
|
||||
{
|
||||
onClientDone(ec, msg);
|
||||
});
|
||||
_client.done().connect([this](Wt::AsioWrapper::error_code ec, const Wt::Http::Message& msg) {
|
||||
_strand.dispatch([this, ec, msg = std::move(msg)] {
|
||||
onClientDone(ec, msg);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
SendQueue::~SendQueue()
|
||||
@@ -79,13 +77,12 @@ namespace lms::core::http
|
||||
|
||||
void SendQueue::sendRequest(std::unique_ptr<ClientRequest> request)
|
||||
{
|
||||
boost::asio::dispatch(_strand, [this, request = std::move(request)]() mutable
|
||||
{
|
||||
_sendQueue[request->getParameters().priority].emplace_back(std::move(request));
|
||||
boost::asio::dispatch(_strand, [this, request = std::move(request)]() mutable {
|
||||
_sendQueue[request->getParameters().priority].emplace_back(std::move(request));
|
||||
|
||||
if (_state == State::Idle)
|
||||
sendNextQueuedRequest();
|
||||
});
|
||||
if (_state == State::Idle)
|
||||
sendNextQueuedRequest();
|
||||
});
|
||||
}
|
||||
|
||||
void SendQueue::sendNextQueuedRequest()
|
||||
@@ -220,21 +217,20 @@ namespace lms::core::http
|
||||
LOG(DEBUG, "Throttling for " << duration.count() << " seconds");
|
||||
|
||||
_throttleTimer.expires_after(duration);
|
||||
_throttleTimer.async_wait([this](const boost::system::error_code& ec)
|
||||
_throttleTimer.async_wait([this](const boost::system::error_code& ec) {
|
||||
if (ec == boost::asio::error::operation_aborted)
|
||||
{
|
||||
if (ec == boost::asio::error::operation_aborted)
|
||||
{
|
||||
LOG(DEBUG, "Throttle aborted");
|
||||
return;
|
||||
}
|
||||
else if (ec)
|
||||
{
|
||||
throw LmsException{ "Throttle timer failure: " + std::string {ec.message()} };
|
||||
}
|
||||
LOG(DEBUG, "Throttle aborted");
|
||||
return;
|
||||
}
|
||||
else if (ec)
|
||||
{
|
||||
throw LmsException{ "Throttle timer failure: " + std::string{ ec.message() } };
|
||||
}
|
||||
|
||||
_state = State::Idle;
|
||||
sendNextQueuedRequest();
|
||||
});
|
||||
_state = State::Idle;
|
||||
sendNextQueuedRequest();
|
||||
});
|
||||
_state = State::Throttled;
|
||||
}
|
||||
}
|
||||
} // namespace lms::core::http
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <Wt/Http/Client.h>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/io_context_strand.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
|
||||
#include <Wt/Http/Client.h>
|
||||
#include "ClientRequest.hpp"
|
||||
|
||||
namespace lms::core::http
|
||||
@@ -53,15 +53,15 @@ namespace lms::core::http
|
||||
void onClientDoneSuccess(std::unique_ptr<ClientRequest> request, const Wt::Http::Message& msg);
|
||||
void throttle(std::chrono::seconds duration);
|
||||
|
||||
const std::size_t _maxRetryCount{ 2 };
|
||||
const std::chrono::seconds _defaultRetryWaitDuration{ 30 };
|
||||
const std::chrono::seconds _minRetryWaitDuration{ 1 };
|
||||
const std::chrono::seconds _maxRetryWaitDuration{ 300 };
|
||||
const std::size_t _maxRetryCount{ 2 };
|
||||
const std::chrono::seconds _defaultRetryWaitDuration{ 30 };
|
||||
const std::chrono::seconds _minRetryWaitDuration{ 1 };
|
||||
const std::chrono::seconds _maxRetryWaitDuration{ 300 };
|
||||
|
||||
boost::asio::io_context& _ioContext;
|
||||
boost::asio::io_context::strand _strand{ _ioContext };
|
||||
boost::asio::steady_timer _throttleTimer{ _ioContext };
|
||||
std::string _baseUrl;
|
||||
boost::asio::io_context::strand _strand{ _ioContext };
|
||||
boost::asio::steady_timer _throttleTimer{ _ioContext };
|
||||
std::string _baseUrl;
|
||||
|
||||
enum class State
|
||||
{
|
||||
@@ -69,10 +69,10 @@ namespace lms::core::http
|
||||
Throttled,
|
||||
Sending,
|
||||
};
|
||||
State _state{ State::Idle };
|
||||
Wt::Http::Client _client{ _ioContext };
|
||||
State _state{ State::Idle };
|
||||
Wt::Http::Client _client{ _ioContext };
|
||||
std::map<ClientRequestParameters::Priority, std::deque<std::unique_ptr<ClientRequest>>> _sendQueue;
|
||||
std::unique_ptr<ClientRequest> _currentRequest;
|
||||
std::unique_ptr<ClientRequest> _currentRequest;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace lms::core::http
|
||||
Reference in New Issue
Block a user