1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-28 11:42:42 +01:00

Add timeout functionality -- mostly. Still have to figure out the best

way to store items in case too much time has elapsed.
This commit is contained in:
Jeff Mitchell 2011-07-06 14:58:56 -04:00
parent 6bb26ecde8
commit 226f823354
4 changed files with 81 additions and 13 deletions

View File

@ -119,18 +119,18 @@ InfoSystem::newNam() const
void
InfoSystem::getInfo( const QString &caller, const InfoType type, const QVariant& input, QVariantMap customData )
InfoSystem::getInfo( const QString &caller, const InfoType type, const QVariant& input, QVariantMap customData, uint timeoutMillis )
{
qDebug() << Q_FUNC_INFO;
QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) );
QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ), Q_ARG( uint, timeoutMillis ) );
}
void
InfoSystem::getInfo( const QString &caller, const InfoTypeMap &input, QVariantMap customData )
InfoSystem::getInfo( const QString &caller, const InfoTypeMap &inputMap, QVariantMap customData, const InfoTimeoutMap &timeoutMap )
{
Q_FOREACH( InfoType type, input.keys() )
QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input[ type ] ), Q_ARG( QVariantMap, customData ) );
Q_FOREACH( InfoType type, inputMap.keys() )
QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, inputMap[ type ] ), Q_ARG( QVariantMap, customData ), Q_ARG( uint, ( timeoutMap.contains( type ) ? timeoutMap[ type ] : 3000 ) ) );
}

View File

@ -108,6 +108,7 @@ enum InfoType { // as items are saved in cache, mark them here to not change the
};
typedef QMap< InfoType, QVariant > InfoTypeMap;
typedef QMap< InfoType, uint > InfoTimeoutMap;
typedef QMap< QString, QMap< QString, QString > > InfoGenericMap;
typedef QHash< QString, QString > InfoCriteriaHash;
@ -157,8 +158,8 @@ public:
InfoSystem( QObject *parent );
~InfoSystem();
void getInfo( const QString &caller, const InfoType type, const QVariant &input, QVariantMap customData );
void getInfo( const QString &caller, const InfoTypeMap &input, QVariantMap customData );
void getInfo( const QString &caller, const InfoType type, const QVariant &input, QVariantMap customData, uint timeoutSeconds = 3000 );
void getInfo( const QString &caller, const InfoTypeMap &inputMap, QVariantMap customData, const InfoTimeoutMap &timeoutMap = InfoTimeoutMap() );
void pushInfo( const QString &caller, const InfoType type, const QVariant &input );
void pushInfo( const QString &caller, const InfoTypeMap &input );

View File

@ -46,6 +46,11 @@ InfoSystemWorker::InfoSystemWorker()
, m_nextRequest( 0 )
{
qDebug() << Q_FUNC_INFO;
m_checkTimeoutsTimer.setInterval( 1000 );
m_checkTimeoutsTimer.setSingleShot( false );
connect( &m_checkTimeoutsTimer, SIGNAL( timeout() ), SLOT( checkTimeoutsTimerFired() ) );
m_checkTimeoutsTimer.start();
}
@ -149,13 +154,14 @@ InfoSystemWorker::determineOrderedMatches( const InfoType type ) const
void
InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, QVariantMap customData )
InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, QVariantMap customData, uint timeoutMillis )
{
qDebug() << Q_FUNC_INFO;
QLinkedList< InfoPluginPtr > providers = determineOrderedMatches( type );
if ( providers.isEmpty() )
{
emit info( caller, type, QVariant(), QVariant(), customData );
checkFinished( caller );
return;
}
@ -163,15 +169,22 @@ InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, QVaria
if ( !ptr )
{
emit info( caller, type, QVariant(), QVariant(), customData );
checkFinished( caller );
return;
}
uint requestnum = ++m_nextRequest;
qDebug() << "assigning request with requestId " << requestnum;
uint requestId = ++m_nextRequest;
m_requestSatisfiedMap[ requestId ] = false;
if ( timeoutMillis != 0 )
{
qint64 currMs = QDateTime::currentMSecsSinceEpoch();
m_timeRequestMapper.insert( currMs + timeoutMillis, requestId );
}
qDebug() << "assigning request with requestId " << requestId;
m_dataTracker[ caller ][ type ] = m_dataTracker[ caller ][ type ] + 1;
qDebug() << "current count in dataTracker for type" << type << "is" << m_dataTracker[ caller ][ type ];
QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( uint, requestnum ), Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) );
QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( uint, requestId ), Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) );
}
@ -192,16 +205,23 @@ void
InfoSystemWorker::infoSlot( uint requestId, QString target, InfoType type, QVariant input, QVariant output, QVariantMap customData )
{
qDebug() << Q_FUNC_INFO << " with requestId " << requestId;
qDebug() << "current count in dataTracker for target " << target << " is " << m_dataTracker[ target ][ type ];
if ( m_dataTracker[ target ][ type ] == 0 )
{
qDebug() << "Caller was not waiting for that type of data!";
return;
}
m_requestSatisfiedMap[ requestId ] = true;
emit info( target, type, input, output, customData );
m_dataTracker[ target ][ type ] = m_dataTracker[ target ][ type ] - 1;
qDebug() << "current count in dataTracker for target " << target << " is " << m_dataTracker[ target ][ type ];
checkFinished( target );
}
void
InfoSystemWorker::checkFinished( const QString &target )
{
Q_FOREACH( InfoType testtype, m_dataTracker[ target ].keys() )
{
if ( m_dataTracker[ target ][ testtype ] != 0)
@ -215,6 +235,42 @@ InfoSystemWorker::infoSlot( uint requestId, QString target, InfoType type, QVari
}
void
InfoSystemWorker::checkTimeoutsTimerFired()
{
qint64 currTime = QDateTime::currentMSecsSinceEpoch();
Q_FOREACH( qint64 time, m_timeRequestMapper.keys() )
{
Q_FOREACH( uint requestId, m_timeRequestMapper.values( time ) )
{
if ( time < currTime )
{
if ( m_requestSatisfiedMap[ requestId ] )
{
qDebug() << Q_FUNC_INFO << " removing mapping of " << requestId << " which expired at time " << time << " and was already satisfied";
m_timeRequestMapper.remove( time, requestId );
if ( !m_timeRequestMapper.count( time ) )
m_timeRequestMapper.remove( time );
continue;
}
//doh, timed out
//FIXME: do something
//m_requestSatisfiedMap[ requestId ] = true;
//m_timeRequestMapper.remove( time, requestId );
//if ( !m_timeRequestMapper.count( time ) )
// m_timeRequestMapper.remove( time );
}
else
{
//we've caught up, the remaining requets still have time to work
return;
}
}
}
}
QNetworkAccessManager*
InfoSystemWorker::nam() const
{

View File

@ -29,6 +29,7 @@
#include <QtCore/QSet>
#include <QtCore/QLinkedList>
#include <QtCore/QVariant>
#include <QtCore/QTimer>
#include "dllmacro.h"
@ -55,15 +56,23 @@ signals:
public slots:
void init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > cache );
void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData );
void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData, uint timeoutMillis );
void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input );
void infoSlot( uint requestId, const QString target, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariant output, const QVariantMap customData );
void newNam();
private slots:
void checkTimeoutsTimerFired();
private:
void checkFinished( const QString &target );
QHash< QString, QHash< InfoType, int > > m_dataTracker;
QMultiMap< qint64, uint > m_timeRequestMapper;
QHash< uint, bool > m_requestSatisfiedMap;
QLinkedList< InfoPluginPtr > determineOrderedMatches( const InfoType type ) const;
@ -76,6 +85,8 @@ private:
QWeakPointer< QNetworkAccessManager> m_nam;
uint m_nextRequest;
QTimer m_checkTimeoutsTimer;
};
}