1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-09 07:36:48 +02:00

Merge pull request #174 from tomahawk-player/GeneratorLocking

Implement locking mechanism to only allow one thread to contact echonest...
This commit is contained in:
Christian Muehlhaeuser
2013-03-23 19:13:49 -07:00
2 changed files with 96 additions and 47 deletions

View File

@@ -29,6 +29,7 @@
#include "SourceList.h"
#include <QFile>
#include <QDir>
#include <QReadWriteLock>
#include <EchonestCatalogSynchronizer.h>
using namespace Tomahawk;
@@ -41,6 +42,10 @@ QNetworkReply* EchonestGenerator::s_moodsJob = 0;
QNetworkReply* EchonestGenerator::s_stylesJob = 0;
QNetworkReply* EchonestGenerator::s_genresJob = 0;
static QReadWriteLock s_moods_lock;
static QReadWriteLock s_styles_lock;
static QReadWriteLock s_genres_lock;
CatalogManager* EchonestGenerator::s_catalogs = 0;
@@ -615,60 +620,94 @@ EchonestGenerator::loadStylesMoodsAndGenres()
{
if( !s_styles.isEmpty() && !s_moods.isEmpty() && !s_genres.isEmpty() )
return;
loadStyles();
loadMoods();
loadGenres();
}
void
EchonestGenerator::loadStyles()
{
if ( s_styles.isEmpty() )
{
QVariant styles = TomahawkUtils::Cache::instance()->getData( "EchonesGenerator", "styles" );
if ( styles.isValid() && styles.canConvert< QStringList >() )
if ( s_styles_lock.tryLockForRead() )
{
s_styles = styles.toStringList();
QVariant styles = TomahawkUtils::Cache::instance()->getData( "EchonesGenerator", "styles" );
s_styles_lock.unlock();
if ( styles.isValid() && styles.canConvert< QStringList >() )
{
s_styles = styles.toStringList();
}
else
{
s_styles_lock.lockForWrite();
tLog() << "Styles not in cache or too old, refetching styles ...";
s_stylesJob = Echonest::Artist::listTerms( "style" );
connect( s_stylesJob, SIGNAL( finished() ), this, SLOT( stylesReceived() ) );
}
}
else
{
tLog() << "Styles not in cache or too old, refetching styles ...";
s_stylesJob = Echonest::Artist::listTerms( "style" );
connect( s_stylesJob, SIGNAL( finished() ), this, SLOT( stylesReceived() ) );
}
}
if ( s_moods.isEmpty() )
{
QVariant moods = TomahawkUtils::Cache::instance()->getData( "EchonesGenerator", "moods" );
if ( moods.isValid() && moods.canConvert< QStringList >() ) {
s_moods = moods.toStringList();
}
else
{
tLog() << "Moods not in cache or too old, refetching moods ...";
s_moodsJob = Echonest::Artist::listTerms( "mood" );
connect( s_moodsJob, SIGNAL( finished() ), this, SLOT( moodsReceived() ) );
}
}
if ( s_genres.isEmpty() )
{
QVariant genres = TomahawkUtils::Cache::instance()->getData( "EchonesGenerator", "genres" );
if ( genres.isValid() && genres.canConvert< QStringList >() )
{
s_genres = genres.toStringList();
}
else
{
tLog() << "Genres not in cache or too old, refetching genres ...";
s_genresJob = Echonest::Artist::fetchGenres();
connect( s_genresJob, SIGNAL( finished() ), this, SLOT( genresReceived() ) );
connect( this, SIGNAL( stylesSaved() ), this, SLOT( loadStyles() ) );
}
}
}
void
EchonestGenerator::saveStylesMoodsAndGenres()
EchonestGenerator::loadMoods()
{
TomahawkUtils::Cache::instance()->putData( "EchonesGenerator", 1209600000 /* 2 weeks */, "moods", QVariant::fromValue< QStringList >( s_moods ) );
TomahawkUtils::Cache::instance()->putData( "EchonesGenerator", 1209600000 /* 2 weeks */, "styles", QVariant::fromValue< QStringList >( s_styles ) );
TomahawkUtils::Cache::instance()->putData( "EchonesGenerator", 1209600000 /* 2 weeks */, "genres", QVariant::fromValue< QStringList >( s_genres ) );
if ( s_moods.isEmpty() )
{
if ( s_moods_lock.tryLockForRead() )
{
QVariant moods = TomahawkUtils::Cache::instance()->getData( "EchonesGenerator", "moods" );
s_moods_lock.unlock();
if ( moods.isValid() && moods.canConvert< QStringList >() ) {
s_moods = moods.toStringList();
}
else
{
s_moods_lock.lockForWrite();
tLog() << "Moods not in cache or too old, refetching moods ...";
s_moodsJob = Echonest::Artist::listTerms( "mood" );
connect( s_moodsJob, SIGNAL( finished() ), this, SLOT( moodsReceived() ) );
}
}
else
{
connect( this, SIGNAL( moodsSaved() ), this, SLOT( loadMoods() ) );
}
}
}
void
EchonestGenerator::loadGenres()
{
if ( s_genres.isEmpty() )
{
if ( s_genres_lock.tryLockForRead() )
{
QVariant genres = TomahawkUtils::Cache::instance()->getData( "EchonesGenerator", "genres" );
s_genres_lock.unlock();
if ( genres.isValid() && genres.canConvert< QStringList >() )
{
s_genres = genres.toStringList();
}
else
{
s_genres_lock.lockForWrite();
tLog() << "Genres not in cache or too old, refetching genres ...";
s_genresJob = Echonest::Artist::fetchGenres();
connect( s_genresJob, SIGNAL( finished() ), this, SLOT( genresReceived() ) );
}
}
else
{
connect( this, SIGNAL( genresSaved() ), this, SLOT( loadGenres() ) );
}
}
}
QStringList
EchonestGenerator::moods()
@@ -693,8 +732,9 @@ EchonestGenerator::moodsReceived()
}
s_moodsJob = 0;
if( !s_styles.isEmpty() && !s_genres.isEmpty() )
saveStylesMoodsAndGenres();
TomahawkUtils::Cache::instance()->putData( "EchonesGenerator", 1209600000 /* 2 weeks */, "moods", QVariant::fromValue< QStringList >( s_moods ) );
s_moods_lock.unlock();
emit moodsSaved();
}
@@ -721,8 +761,9 @@ EchonestGenerator::stylesReceived()
}
s_stylesJob = 0;
if( !s_moods.isEmpty() && !s_styles.isEmpty() )
saveStylesMoodsAndGenres();
TomahawkUtils::Cache::instance()->putData( "EchonesGenerator", 1209600000 /* 2 weeks */, "styles", QVariant::fromValue< QStringList >( s_styles ) );
s_styles_lock.unlock();
emit stylesSaved();
}
QStringList
@@ -747,6 +788,7 @@ EchonestGenerator::genresReceived()
}
s_genresJob = 0;
if( !s_moods.isEmpty() && !s_styles.isEmpty() )
saveStylesMoodsAndGenres();
TomahawkUtils::Cache::instance()->putData( "EchonesGenerator", 1209600000 /* 2 weeks */, "genres", QVariant::fromValue< QStringList >( s_genres ) );
s_genres_lock.unlock();
emit genresSaved();
}

View File

@@ -90,6 +90,10 @@ public:
signals:
void paramsGenerated( const Echonest::DynamicPlaylist::PlaylistParams& );
void stylesSaved();
void moodsSaved();
void genresSaved();
private slots:
void staticFinished();
void dynamicStarted();
@@ -98,6 +102,10 @@ private slots:
void doGenerate( const Echonest::DynamicPlaylist::PlaylistParams& params );
void doStartOnDemand( const Echonest::DynamicPlaylist::PlaylistParams& params );
void loadStyles();
void loadMoods();
void loadGenres();
void stylesReceived();
void moodsReceived();
void genresReceived();
@@ -113,7 +121,6 @@ private:
bool onlyThisArtistType( Echonest::DynamicPlaylist::ArtistTypeEnum type ) const throw( std::runtime_error );
void loadStylesMoodsAndGenres();
void saveStylesMoodsAndGenres();
Echonest::DynamicPlaylist* m_dynPlaylist;
QPixmap m_logo;