Further decoupled recommendation engine: it now has its own thread

This commit is contained in:
emeric
2020-02-16 12:39:27 +01:00
parent 6239064396
commit a414a80bbb
12 changed files with 280 additions and 184 deletions
+72 -31
View File
@@ -23,46 +23,51 @@
#include "recommendation/FeaturesClassifierCreator.hpp"
#include "database/ScanSettings.hpp"
#include "database/Session.hpp"
#include "database/TrackList.hpp"
#include "utils/Logger.hpp"
namespace Recommendation {
std::unique_ptr<IEngine>
createEngine(Database::Session& session)
createEngine(Database::Db& db)
{
return std::make_unique<Engine>(session);
return std::make_unique<Engine>(db);
}
Engine::Engine(Database::Session& session)
Engine::Engine(Database::Db& db)
: _dbSession {db}
{
reload(session);
}
void
Engine::reload(Database::Session& session)
Engine::start()
{
using namespace Database;
assert(!_running);
_running = true;
const ScanSettings::RecommendationEngineType engineType {[&]()
requestReload();
_ioService.start();
}
void
Engine::stop()
{
assert(_running);
_running = false;
_ioService.stop();
}
void
Engine::requestReload()
{
LMS_LOG(RECOMMENDATION, DEBUG) << "Reload requested...";
_ioService.post([&]()
{
auto transaction {session.createSharedTransaction()};
return ScanSettings::get(session)->getRecommendationEngineType();
}()};
// TODO: just replace the classifier once it is ready
clearClassifiers();
switch (engineType)
{
case ScanSettings::RecommendationEngineType::Features:
// addClassifier(createFeaturesClassifier(), 0); // higher priority
// [[fallthrough]];
case ScanSettings::RecommendationEngineType::Clusters:
addClassifier(createClustersClassifier(session), 1); // lower priority
break;
}
reload();
});
}
std::vector<Database::IdType>
@@ -85,7 +90,7 @@ Engine::getSimilarTracksFromTrackList(Database::Session& session, Database::IdTy
if (trackIds.empty())
return {};
std::shared_lock lock {_mutex};
std::shared_lock lock {_classifiersMutex};
for (const auto& [priority, classifier] : _classifiers)
{
@@ -99,7 +104,7 @@ Engine::getSimilarTracksFromTrackList(Database::Session& session, Database::IdTy
std::vector<Database::IdType>
Engine::getSimilarTracks(Database::Session& dbSession, const std::unordered_set<Database::IdType>& trackIds, std::size_t maxCount)
{
std::shared_lock lock {_mutex};
std::shared_lock lock {_classifiersMutex};
for (const auto& [priority, classifier] : _classifiers)
{
@@ -113,7 +118,7 @@ Engine::getSimilarTracks(Database::Session& dbSession, const std::unordered_set<
std::vector<Database::IdType>
Engine::getSimilarReleases(Database::Session& dbSession, Database::IdType releaseId, std::size_t maxCount)
{
std::shared_lock lock {_mutex};
std::shared_lock lock {_classifiersMutex};
for (const auto& [priority, classifier] : _classifiers)
{
@@ -127,7 +132,7 @@ Engine::getSimilarReleases(Database::Session& dbSession, Database::IdType releas
std::vector<Database::IdType>
Engine::getSimilarArtists(Database::Session& dbSession, Database::IdType artistId, std::size_t maxCount)
{
std::shared_lock lock {_mutex};
std::shared_lock lock {_classifiersMutex};
for (const auto& [priority, classifier] : _classifiers)
{
@@ -138,17 +143,53 @@ Engine::getSimilarArtists(Database::Session& dbSession, Database::IdType artistI
return {};
}
void
Engine::reload()
{
using namespace Database;
LMS_LOG(RECOMMENDATION, DEBUG) << "Reloading recommendation engines...";
const ScanSettings::RecommendationEngineType engineType {[&]()
{
auto transaction {_dbSession.createSharedTransaction()};
return ScanSettings::get(_dbSession)->getRecommendationEngineType();
}()};
// TODO: just replace the classifier once it is ready
clearClassifiers();
switch (engineType)
{
case ScanSettings::RecommendationEngineType::Features:
// addClassifier(createFeaturesClassifier(), 0); // higher priority
// [[fallthrough]];
case ScanSettings::RecommendationEngineType::Clusters:
addClassifier(createClustersClassifier(_dbSession), 1); // lower priority
break;
}
LMS_LOG(RECOMMENDATION, DEBUG) << "Recommendation engines reloaded!";
_sigReloaded.emit();
}
void
Engine::clearClassifiers()
{
std::unique_lock lock {_mutex};
std::unique_lock lock {_classifiersMutex};
_classifiers.clear();
}
void
Engine::addClassifier(std::unique_ptr<IClassifier> classifier, unsigned priority)
{
std::unique_lock lock {_mutex};
std::unique_lock lock {_classifiersMutex};
_classifiers.emplace(priority, std::move(classifier));
}