Commit 57f5ceb0 authored by Volker Krause's avatar Volker Krause
Browse files

- Add JobQueue convenience class for sequential execution of a large

  number of jobs using the same backend connection.
- Add a test program that creates a large number of collections to
  compare parallel and and sequential execution. It also shows
  problems with concurrent write access in the backend.

svn path=/trunk/KDE/kdepim/libakonadi/; revision=548016
parent 3e58c75f
......@@ -13,7 +13,6 @@ include_directories(
set( akonadi_LIB_SRC
datarequest.cpp
job.cpp
query.cpp
collection.cpp
collectioncreatejob.cpp
......@@ -26,6 +25,8 @@ set( akonadi_LIB_SRC
imapparser.cpp
item.cpp
itemappendjob.cpp
job.cpp
jobqueue.cpp
messagecollection.cpp
messagecollectionmodel.cpp
message.cpp
......@@ -47,7 +48,6 @@ install_targets( ${LIB_INSTALL_DIR} akonadi )
install_files( /include/libakonadi FILES
datarequest.h
job.h
query.h
collection.h
collectioncreatejob.h
......@@ -60,6 +60,8 @@ install_files( /include/libakonadi FILES
imapparser.h
item.h
itemappendjob.h
job.h
jobqueue.h
messagecollection.h
messagecollectionmodel.h
message.h
......
......@@ -58,4 +58,9 @@ void PIM::CollectionCreateJob::handleResponse( const QByteArray & tag, const QBy
qDebug() << "unhandled response in collection create job: " << tag << data;
}
QByteArray PIM::CollectionCreateJob::path( ) const
{
return d->path;
}
#include "collectioncreatejob.moc"
......@@ -45,6 +45,11 @@ class AKONADI_EXPORT CollectionCreateJob : public Job
*/
virtual ~CollectionCreateJob();
/**
Returns the path of the collection this job is supposed to create.
*/
QByteArray path() const;
protected:
virtual void doStart();
virtual void handleResponse( const QByteArray &tag, const QByteArray &data );
......
/*
Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "jobqueue.h"
#include <QDebug>
#include <QQueue>
using namespace PIM;
class PIM::JobQueuePrivate
{
public:
QQueue<Job*> queue;
bool isStarted;
bool jobRunning;
};
PIM::JobQueue::JobQueue( QObject * parent ) :
Job( parent ),
d( new JobQueuePrivate )
{
d->isStarted = false;
d->jobRunning = false;
start();
}
PIM::JobQueue::~ JobQueue( )
{
// TODO: what to do about still enqueued jobs?
delete d;
}
void PIM::JobQueue::addJob( PIM::Job * job )
{
d->queue.enqueue( job );
startNext();
}
void PIM::JobQueue::doStart( )
{
d->isStarted = true;
startNext();
}
void PIM::JobQueue::jobDone( PIM::Job * job )
{
Q_UNUSED( job );
d->jobRunning = false;
startNext();
}
void PIM::JobQueue::startNext( )
{
if ( !d->isStarted || d->jobRunning || isEmpty() )
return;
Job *job = d->queue.dequeue();
connect( job, SIGNAL(done(PIM::Job*)), SLOT(jobDone(PIM::Job*)) );
job->start();
}
bool PIM::JobQueue::isEmpty( ) const
{
return d->queue.isEmpty();
}
void PIM::JobQueue::start( )
{
Job::start();
}
#include "jobqueue.moc"
/*
Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef PIM_JOBQUEUE_H
#define PIM_JOBQUEUE_H
#include <libakonadi/job.h>
namespace PIM {
class JobQueuePrivate;
/**
A job queue. All jobs you put in here are executed sequentially. JobQueue can
be used as a parent for jobs to share the same connection to the Akonadi
backend. Do not start enqueued jobs manually!
*/
class AKONADI_EXPORT JobQueue : public Job
{
Q_OBJECT
public:
/**
Create a new job queue.
@param parent The parent object.
*/
JobQueue( QObject *parent = 0 );
/**
Destroys this object.
*/
virtual ~JobQueue();
/**
Adds the given job to the queue. Added jobs will be started automatically.
*/
void addJob( PIM::Job* job );
/**
Returns true if there are no jobs in the queue.
*/
bool isEmpty() const;
protected:
virtual void doStart();
private:
// part of the Job API, hide it for JobQueue
virtual void start();
void startNext();
private slots:
void jobDone( PIM::Job* job );
private:
JobQueuePrivate *d;
};
}
#endif
......@@ -7,6 +7,16 @@ include_directories(
${CMAKE_SOURCE_DIR}/libkmime
)
# convenience macro to add akonadi demo application
macro(add_akonadi_demo _source)
set(_test ${_source})
get_filename_component(_name ${_source} NAME_WE)
kde4_automoc(${_test})
kde4_add_executable(${_name} RUN_UNINSTALLED ${_test})
target_link_libraries(${_name} akonadi)
endmacro(add_akonadi_demo)
# convenience macro to add akonadi qtestlib unit-tests
macro(add_akonadi_test _source)
set(_test ${_source})
......@@ -37,15 +47,10 @@ kde4_add_executable(messagebrowser RUN_UNINSTALLED ${messagebrowser_SRCS})
target_link_libraries(messagebrowser akonadi ${KDE4_KDECORE_LIBS} )
########### next target ###############
set(itemdumper_SRCS itemdumper.cpp )
kde4_automoc(${itemdumper_SRCS})
kde4_add_executable(itemdumper RUN_UNINSTALLED ${itemdumper_SRCS})
target_link_libraries(itemdumper akonadi ${KDE4_KDECORE_LIBS} )
# demo applications
add_akonadi_demo(itemdumper.cpp)
add_akonadi_demo(collectioncreator.cpp)
# qtestlib unit tests
add_akonadi_test(imapparsertest.cpp)
......
/*
Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "collectioncreator.h"
#include "collectioncreatejob.h"
#include <QApplication>
#include <QDebug>
#include <kapplication.h>
#include <kcmdlineargs.h>
#define COLLECTION_COUNT 100
#undef SEQUENTIAL_EXECUTION
using namespace PIM;
CollectionCreator::CollectionCreator( )
{
#ifdef SEQUENTIAL_EXECUTION
queue = new JobQueue( this );
#else
jobCount = 0;
#endif
startTime = QTime::currentTime();
for ( int i = 0; i < COLLECTION_COUNT; ++i ) {
#ifdef SEQUENTIAL_EXECUTION
CollectionCreateJob *job = new CollectionCreateJob( "res3/col" + QByteArray::number( i ), queue );
connect( job, SIGNAL(done(PIM::Job*)), SLOT(done(PIM::Job*)) );
queue->addJob( job );
#else
CollectionCreateJob *job = new CollectionCreateJob( "res3/col" + QByteArray::number( i ), this );
connect( job, SIGNAL(done(PIM::Job*)), SLOT(done(PIM::Job*)) );
job->start();
++jobCount;
#endif
}
}
void CollectionCreator::done( PIM::Job * job )
{
#ifndef SEQUENTIAL_EXECUTION
--jobCount;
#endif
if ( job->error() ) {
qWarning() << "Creation failed: " << job->errorText();
}
job->deleteLater();
#ifdef SEQUENTIAL_EXECUTION
if ( queue->isEmpty() ) {
#else
if ( jobCount <= 0 ) {
#endif
qDebug() << "creation took: " << startTime.secsTo( QTime::currentTime() ) << " seconds.";
qApp->quit();
}
}
int main( int argc, char** argv )
{
KCmdLineArgs::init( argc, argv, "test", "Test" ,"test app" ,"1.0" );
KApplication app;
CollectionCreator *cc = new CollectionCreator();
return app.exec();
delete cc;
}
#include "collectioncreator.moc"
/*
Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef COLLECTIONCREATOR_H
#define COLLECTIONCREATOR_H
#include <QtCore/QObject>
#include <QtCore/QTime>
#include <libakonadi/job.h>
#include <libakonadi/jobqueue.h>
class CollectionCreator : public QObject
{
Q_OBJECT
public:
CollectionCreator();
private slots:
void done(PIM::Job* job);
private:
int jobCount;
QTime startTime;
PIM::JobQueue *queue;
};
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment