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:
parent
6bb26ecde8
commit
226f823354
@ -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 ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user