akonadi
resourcesynchronizationjob.cpp
00001 /* 00002 * Copyright (c) 2009 Volker Krause <vkrause@kde.org> 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #include "resourcesynchronizationjob.h" 00019 #include "dbusconnectionpool.h" 00020 #include "kjobprivatebase_p.h" 00021 00022 #include <akonadi/agentinstance.h> 00023 #include <akonadi/agentmanager.h> 00024 00025 #include <KDebug> 00026 #include <KLocale> 00027 00028 #include <QDBusConnection> 00029 #include <QDBusInterface> 00030 #include <QTimer> 00031 00032 namespace Akonadi 00033 { 00034 00035 class ResourceSynchronizationJobPrivate : public KJobPrivateBase 00036 { 00037 public: 00038 ResourceSynchronizationJobPrivate( ResourceSynchronizationJob* parent ) : 00039 q( parent ), 00040 interface( 0 ), 00041 safetyTimer( 0 ), 00042 timeoutCount( 0 ) 00043 {} 00044 00045 void doStart(); 00046 00047 ResourceSynchronizationJob *q; 00048 AgentInstance instance; 00049 QDBusInterface* interface; 00050 QTimer* safetyTimer; 00051 int timeoutCount; 00052 static int timeoutCountLimit; 00053 00054 void slotSynchronized(); 00055 void slotTimeout(); 00056 }; 00057 00058 int ResourceSynchronizationJobPrivate::timeoutCountLimit = 60; 00059 00060 ResourceSynchronizationJob::ResourceSynchronizationJob(const AgentInstance& instance, QObject* parent) : 00061 KJob( parent ), 00062 d( new ResourceSynchronizationJobPrivate( this ) ) 00063 { 00064 d->instance = instance; 00065 d->safetyTimer = new QTimer( this ); 00066 connect( d->safetyTimer, SIGNAL( timeout() ), SLOT( slotTimeout() ) ); 00067 d->safetyTimer->setInterval( 10 * 1000 ); 00068 d->safetyTimer->setSingleShot( false ); 00069 } 00070 00071 ResourceSynchronizationJob::~ResourceSynchronizationJob() 00072 { 00073 delete d; 00074 } 00075 00076 void ResourceSynchronizationJob::start() 00077 { 00078 d->start(); 00079 } 00080 00081 void ResourceSynchronizationJobPrivate::doStart() 00082 { 00083 if ( !instance.isValid() ) { 00084 q->setError( KJob::UserDefinedError ); 00085 q->setErrorText( i18n( "Invalid resource instance." ) ); 00086 q->emitResult(); 00087 return; 00088 } 00089 00090 interface = new QDBusInterface( QString::fromLatin1( "org.freedesktop.Akonadi.Resource.%1" ).arg( instance.identifier() ), 00091 QString::fromLatin1( "/" ), 00092 QString::fromLatin1( "org.freedesktop.Akonadi.Resource" ), 00093 DBusConnectionPool::threadConnection(), this ); 00094 connect( interface, SIGNAL( synchronized() ), q, SLOT( slotSynchronized() ) ); 00095 00096 if ( interface->isValid() ) { 00097 instance.synchronize(); 00098 safetyTimer->start(); 00099 } else { 00100 q->setError( KJob::UserDefinedError ); 00101 q->setErrorText( i18n( "Unable to obtain D-Bus interface for resource '%1'", instance.identifier() ) ); 00102 q->emitResult(); 00103 return; 00104 } 00105 } 00106 00107 void ResourceSynchronizationJobPrivate::slotSynchronized() 00108 { 00109 q->disconnect( interface, SIGNAL( synchronized() ), q, SLOT( slotSynchronized() ) ); 00110 safetyTimer->stop(); 00111 q->emitResult(); 00112 } 00113 00114 void ResourceSynchronizationJobPrivate::slotTimeout() 00115 { 00116 instance = AgentManager::self()->instance( instance.identifier() ); 00117 timeoutCount++; 00118 00119 if ( timeoutCount > timeoutCountLimit ) { 00120 safetyTimer->stop(); 00121 q->setError( KJob::UserDefinedError ); 00122 q->setErrorText( i18n( "Resource synchronization timed out." ) ); 00123 q->emitResult(); 00124 return; 00125 } 00126 00127 if ( instance.status() == AgentInstance::Idle ) { 00128 // try again, we might have lost the synchronized() signal 00129 kDebug() << "trying again to sync resource" << instance.identifier(); 00130 instance.synchronize(); 00131 } 00132 } 00133 00134 AgentInstance ResourceSynchronizationJob::resource() const 00135 { 00136 return d->instance; 00137 } 00138 00139 } 00140 00141 #include "resourcesynchronizationjob.moc"