Difference between revisions of "IUP ISI/MediaWiki-Silk/Architecture"

Jump to: navigation, search
m (fmt)
(Test)
 
(23 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
== Introduction ==
 
== Introduction ==
  
'''API'''
+
This document presents the architecture of LibMediaWiki. It is a library based on Qt/KDE framework wich interface Mediawiki to provides mediawiki fonction for developpers.
  
The API is composed of some classes (UserGroup, Namespace, General, Page...) and a MediaWiki class to access data.
+
'''Purpose'''
'''
 
Library architecture at the begining'''
 
  
The library is composed of a unique class: MediaWiki.
+
This document provides a high level overview of the evolving technical architecture for the Mediawiki Library. It outline the technologies and the technical choice that Library developper will use to develop it.
 +
 
 +
'''References'''
 +
 
 +
*QT Framework is a cross platform Library http://doc.qt.nokia.com/4.7/
 +
*KDE is an open source desktop and Library based on QT http://kde.org/
 +
*MediaWiki is a free software wiki package written in PHP, originally for use on Wikipedia http://www.mediawiki.org/wiki/MediaWiki
  
 
== Choice architecture ==
 
== Choice architecture ==
Line 13: Line 17:
 
'''Synchronous or asynchronous?'''
 
'''Synchronous or asynchronous?'''
  
Synchronous
+
Two choices are possible to develop the request management in the library: synchronous and asynchronous.
* Advantage
+
 
** No signals in the public API
+
Synchronous way will lead us to use normal function call. But, since we expects the end of the function, the interface can freeze especially if there is a lot of latency. Moreover, this way will allow to not use signals.
* Disadvantage
+
 
** Multi-threads when used in interface to avoid freeze
+
Asynchronous way don’t block the interface because the application doesn’t wait the result of each request to execute the program. This method will lead us to use signals to access to the result.
** Latency troubles may increase waiting
+
 
 +
On the one hand, use synchronous way will lead to use a QEventloop to avoid the freezing and a QNetworkAccessManager in synchronous mode. Otherwise, this way can involve the use of different threads in the application.
 +
 
 +
On the other hand, use asynchronous way will lead us to use signals and a QNetworkAccessManager in asynchronous mode.
 +
 
 +
To conclude, we choose the asynchronous one because it solves the interface problem. Moreover, this method is the one used in the library architecture at the begining. But the asynchronous way give the problem of access to the result.
 +
 
 +
'''Get the request’s result'''
  
Asynchronous
+
We can use three methods to get the result.
* Advantage
+
First, we can develop accessors on each  request classes. This way can cause risks of a call before the signal. This method use a synchronous call. A solution can be to specify this trouble in the documentation of the API.
** Don’t block the interface
 
* Disadvantage
 
** Wait the signal to access to the result
 
  
'''Develop Unique class vs multiple classes?'''
+
The second method is to use a signal having the result as parameter. Use of signals, can meet the design pattern command. Indeed this pattern means that the query calls the action to perform, a slot, in the client. Also, this way respect the asynchronous semantic but the result is pass by value. The pass by value will be a trouble because it is something heavy. A possible problem will be that the copy is useless. A solution could be using pass by pointer, smart pointer or reference.
  
Unique class
+
The last method consists in using a signal, like the previous way, which the result as parameter. This method respect the asynchronous semantic but the result is pass by reference. The problem is that the visibility of errors by the slots is lesser.
* Advantage
 
** No memory managing
 
** The request calls are normal : wiki->allpagesRequest()
 
* Disadvantage
 
** Readability
 
  
Multiple classes
+
To conclude, we choose to use two solutions. For the “attribute” classes, a good solution will be to use the first method. As for the “list” classes, the solution will be to use the second solution.
* Advantage
 
** Readability
 
* Disadvantage
 
** The memory management
 
  
== Technical contacts requirements ==
+
'''Develop Unique class vs multiple classes?'''
  
First, the technical contacts want a asynchronous interface: ”Even if you use a QEventLoop,you'll often need different threads in the application, and those can be a bitch. You can have a look at the current MediaWiki class to how those signals / slots should look like.
+
Two choices are possible to create the library: develop a unique class or multiple classes.
  
Secondly, to call a request, the code should look like:
+
A unique class involves that all requests will be within. Another point is that there will be no memory management because only the destruction of the MediaWiki class would be sufficient to. Nevertheless, the presence of all requests hinders the code’s readability. Finally, use this way requires the application to handle a single request at a time.
  MediaWiki * mw = new MediaWiki(“mon_url”);
 
  mw->allpagesRequest();
 
  connect(mw, SIGNAL(allpagesResult(QList<MediaWiki::Page>)),
 
              SLOT(allpagesProcess(QList<MediaWiki::Page>));
 
  
== MediaWiki UML ==
+
Multiple classes will lead us to put one request in one class. This kind of development causes
[[File:Uml.png]]
 
  
'''MediaWiki'''
+
an attentive memory management. On the other hand, this way improves the readability and especially allows to initiate some requests at a time.
  
The MediaWiki class allows developers to call asynchronous request to access the
+
Use a unique class means that all methods will be called in a normal way, for example for calling all pages we must do wiki->allpagesRequest(). We could find a way to allow the application to handle some requests but it will be quite difficult and take a lot of time. To improve the readability, we could put many comments in the code.
MediaWiki data. For this, developers call a request like allpagesRequest() who send the request with the QNetworkAccessManager. To process the result, developers connect the signal allpagesResult() with his own slot.
 
Because the class MediaWiki needs to emit signals, MediaWiki inherit QObject.
 
  
'''Why don’t separate the code'''
+
Use multiple classes leads us to pass a reference to a MediaWiki instance in the constructor of each classes. Finally, we have to define the objects life cycle therefore we will lead to manage the memory.
  
To follow the first development of the MediaWiki class and with the agreement of the technical contacts, we don’t separate MediaWiki and its requests.
+
To conclude, we choose to use some classes because we think that calling many requests is important. Moreover, have a good quality code is a goal. This way is different from the development done at the beginning. However, this method gives the problem of the objects life cycle and the memory management.
  
'''Who manages the memory?'''
+
'''Objects life cycle'''
  
There is one class, so the library can manage the memory.
+
The following schema presents an object life cycle. As we can see, the user instantiate a mediawiki before requesting and destroy it after all requests.
  
'''Why QNetworkAccessManager?'''
+
[[File:MediaWiki_Silk_Sequence_uml.png‎]]
  
It’s the Qt class for HTTP requests and it is asynchronous. By the way, we can use this class in a synchronous way using QEventLoop.
+
'''Memory management'''
  
'''KDE library?'''
+
About the memory management, our classes inherit from KJob which inherit from QObject. An advantage of this class is, if we use parent system, we don’t have to look after the deleting because it will be deleted by itself.
  
At this time, we don’t use KDE library because Qt provides the necessary.
+
== Requirements ==
  
 
'''Namespace'''
 
'''Namespace'''
Line 84: Line 76:
 
For ensure the binary compatibility, we’ll use only a pointer to MediaWikiPrivate, which will contain attributes. In this case, modify the attributes doesn’t fail a class which uses
 
For ensure the binary compatibility, we’ll use only a pointer to MediaWikiPrivate, which will contain attributes. In this case, modify the attributes doesn’t fail a class which uses
 
MediaWiki.
 
MediaWiki.
 +
 +
== Architecture representation ==
 +
 +
The following schema presents an abstract representation of the library.  Also we can see that the library inherits KJob class which inherits QObjects itself.
 +
 +
[[File:MediaWiki_Silk_Class_diagram.png‎]]
 +
 +
== Quality ==
 +
 +
In this part, we will present two pieces of the quality. First, we are going to define the tests architecture. Secondly we will describe the coding style.
 +
 +
===Test===
 +
 +
'''Test types'''
 +
 +
We decided to do unit tests for each classes to ensure that code meets its design and behaves as intended.
 +
 +
Then, to ensure the quality of unit tests, we decided to measure the coverage, it describes the degree to which the source code of a program has been tested. It is a form of testing that inspects the code directly and is therefore a form of white box testing. We add code coverage because it’s easily set and it increases code visibility and quality.
 +
 +
'''Folder organisation'''
 +
 +
We will create a test folder in each project folder. For example, in the libmediawiki folder we will create a test folder, named “test” (“mediawiki/libmediawiki/test”). For each classes, a test class file will be created.
 +
 +
'''Tools'''
 +
 +
We will use CTest to execute tests, it’s a cross-platform, open-source testing system distributed with CMake. CTest can peform several operations on the source code, that include configure, build, perform set of predefined runtime tests. It also includes several advanced tests such as coverage and memory checking.
 +
 +
We have decided to use CTest to work with the same distribution as CMake.
 +
 +
The test ouput results will be displayed on a console or with XML and HTML.
 +
 +
Unit test:
 +
 +
In the unit test code, we have decided to use QTest because we wanted as much as possible to use the Qt library to avoid dependency with other library.
 +
 +
Code coverage test:
 +
 +
For the code coverage we will use GCov, it’s a code coverage program, it will allow us to easily add new tests and to automate tests execution.
 +
 +
'''Local test server'''
 +
 +
To run tests we need a server, we decided to implement a local server (fake server).
 +
In opposition to a web server, here are local server advantages :
 +
* Environment independence, we not depend on a web server then there is not Internet problems because latency can increase the test execution period and make our tests unusable. Moreover our local server don’t need any maintenance operation.
 +
* Keep control on data, tester can keep control on data and avoid that data could be forged by any other tester.
 +
 +
===Coding style===
 +
 +
The project is based on KDE so we decide to follow the kdelibs coding style. For this, we will use the Artistic Style (astyle), it is an automatic code formatting tool. For more information on our coding style, you can click [[IUP ISI/MediaWiki-Silk/coding-style|here]].

Latest revision as of 21:04, 5 November 2010

Introduction

This document presents the architecture of LibMediaWiki. It is a library based on Qt/KDE framework wich interface Mediawiki to provides mediawiki fonction for developpers.

Purpose

This document provides a high level overview of the evolving technical architecture for the Mediawiki Library. It outline the technologies and the technical choice that Library developper will use to develop it.

References

Choice architecture

Synchronous or asynchronous?

Two choices are possible to develop the request management in the library: synchronous and asynchronous.

Synchronous way will lead us to use normal function call. But, since we expects the end of the function, the interface can freeze especially if there is a lot of latency. Moreover, this way will allow to not use signals.

Asynchronous way don’t block the interface because the application doesn’t wait the result of each request to execute the program. This method will lead us to use signals to access to the result.

On the one hand, use synchronous way will lead to use a QEventloop to avoid the freezing and a QNetworkAccessManager in synchronous mode. Otherwise, this way can involve the use of different threads in the application.

On the other hand, use asynchronous way will lead us to use signals and a QNetworkAccessManager in asynchronous mode.

To conclude, we choose the asynchronous one because it solves the interface problem. Moreover, this method is the one used in the library architecture at the begining. But the asynchronous way give the problem of access to the result.

Get the request’s result

We can use three methods to get the result. First, we can develop accessors on each request classes. This way can cause risks of a call before the signal. This method use a synchronous call. A solution can be to specify this trouble in the documentation of the API.

The second method is to use a signal having the result as parameter. Use of signals, can meet the design pattern command. Indeed this pattern means that the query calls the action to perform, a slot, in the client. Also, this way respect the asynchronous semantic but the result is pass by value. The pass by value will be a trouble because it is something heavy. A possible problem will be that the copy is useless. A solution could be using pass by pointer, smart pointer or reference.

The last method consists in using a signal, like the previous way, which the result as parameter. This method respect the asynchronous semantic but the result is pass by reference. The problem is that the visibility of errors by the slots is lesser.

To conclude, we choose to use two solutions. For the “attribute” classes, a good solution will be to use the first method. As for the “list” classes, the solution will be to use the second solution.

Develop Unique class vs multiple classes?

Two choices are possible to create the library: develop a unique class or multiple classes.

A unique class involves that all requests will be within. Another point is that there will be no memory management because only the destruction of the MediaWiki class would be sufficient to. Nevertheless, the presence of all requests hinders the code’s readability. Finally, use this way requires the application to handle a single request at a time.

Multiple classes will lead us to put one request in one class. This kind of development causes

an attentive memory management. On the other hand, this way improves the readability and especially allows to initiate some requests at a time.

Use a unique class means that all methods will be called in a normal way, for example for calling all pages we must do wiki->allpagesRequest(). We could find a way to allow the application to handle some requests but it will be quite difficult and take a lot of time. To improve the readability, we could put many comments in the code.

Use multiple classes leads us to pass a reference to a MediaWiki instance in the constructor of each classes. Finally, we have to define the objects life cycle therefore we will lead to manage the memory.

To conclude, we choose to use some classes because we think that calling many requests is important. Moreover, have a good quality code is a goal. This way is different from the development done at the beginning. However, this method gives the problem of the objects life cycle and the memory management.

Objects life cycle

The following schema presents an object life cycle. As we can see, the user instantiate a mediawiki before requesting and destroy it after all requests.

MediaWiki Silk Sequence uml.png

Memory management

About the memory management, our classes inherit from KJob which inherit from QObject. An advantage of this class is, if we use parent system, we don’t have to look after the deleting because it will be deleted by itself.

Requirements

Namespace

To avoid name conflicts with others libraries, we propose to define a namespace like silk::. mediawiki:: was a possibility but there will be a redundancy (mediawiki::MediaWiki).

Binary compatibility

For ensure the binary compatibility, we’ll use only a pointer to MediaWikiPrivate, which will contain attributes. In this case, modify the attributes doesn’t fail a class which uses MediaWiki.

Architecture representation

The following schema presents an abstract representation of the library. Also we can see that the library inherits KJob class which inherits QObjects itself.

MediaWiki Silk Class diagram.png

Quality

In this part, we will present two pieces of the quality. First, we are going to define the tests architecture. Secondly we will describe the coding style.

Test

Test types

We decided to do unit tests for each classes to ensure that code meets its design and behaves as intended.

Then, to ensure the quality of unit tests, we decided to measure the coverage, it describes the degree to which the source code of a program has been tested. It is a form of testing that inspects the code directly and is therefore a form of white box testing. We add code coverage because it’s easily set and it increases code visibility and quality.

Folder organisation

We will create a test folder in each project folder. For example, in the libmediawiki folder we will create a test folder, named “test” (“mediawiki/libmediawiki/test”). For each classes, a test class file will be created.

Tools

We will use CTest to execute tests, it’s a cross-platform, open-source testing system distributed with CMake. CTest can peform several operations on the source code, that include configure, build, perform set of predefined runtime tests. It also includes several advanced tests such as coverage and memory checking.

We have decided to use CTest to work with the same distribution as CMake.

The test ouput results will be displayed on a console or with XML and HTML.

Unit test:

In the unit test code, we have decided to use QTest because we wanted as much as possible to use the Qt library to avoid dependency with other library.

Code coverage test:

For the code coverage we will use GCov, it’s a code coverage program, it will allow us to easily add new tests and to automate tests execution.

Local test server

To run tests we need a server, we decided to implement a local server (fake server). In opposition to a web server, here are local server advantages :

  • Environment independence, we not depend on a web server then there is not Internet problems because latency can increase the test execution period and make our tests unusable. Moreover our local server don’t need any maintenance operation.
  • Keep control on data, tester can keep control on data and avoid that data could be forged by any other tester.

Coding style

The project is based on KDE so we decide to follow the kdelibs coding style. For this, we will use the Artistic Style (astyle), it is an automatic code formatting tool. For more information on our coding style, you can click here.


This page was last edited on 5 November 2010, at 21:04. Content is available under Creative Commons License SA 4.0 unless otherwise noted.