Précédent   Forum des professionnels en informatique > Bases de données > Firebird
Firebird Forum d'entraide sur le SGBD Firebird. Avant de poster -> F.A.Q Firebird, Tutoriels
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 08/02/2012, 22h22   #1
Invité de passage
 
Homme Jean-Marie
Développeur informatique
Inscription : février 2012
Messages : 5
Détails du profil
Informations personnelles :
Nom : Homme Jean-Marie
Localisation : France, Aube (Champagne Ardenne)

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2012
Messages : 5
Points : 0
Points : 0
Par défaut UIB 2.5 et le MultiThread

Bonjour,
Je suis en train de migrer une application de D2007 / UIB 2.1 / FB 2.1 vers DXE2 / UIB 2.5 / FB 2.5.1
Lors d'appel multiThread UIB je constate assez rapidement des exceptions suite aux appels UIB et dans la couche UIB elle même à divers endroits.
Pour m'affranchir des problèmes applicatifs liés à cette migration, j'ai testé le petit bout de code livré avec UIB (ThreadedQueries dans le dossier uib25\examples\UIB\Component\ThreadedQueries).
Je constate les mêmes problèmes que dans mon appli !
Idem avec FB 2.1
Idem avec base locale ou non.

Voici ce bout de code auquel j'ai ajouté quelques traces. rien de bien transcendant !

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
Unit main;

Interface

Uses
{$IFDEF LINUX}
  libc, QForms, QStdCtrls, QControls, QGraphics, QDialogs, QExtCtrls,
{$ELSE}
  Windows, Graphics, Controls, Forms, Messages, Dialogs, StdCtrls,
{$ENDIF}
  SysUtils, Classes, uib, SyncObjs, JvExStdCtrls, JvMemo, JvTimer;

Type
  TForm1 = Class(TForm)
    DataBase: TUIBDataBase;
    Button1: TButton;
    JvMemo1: TJvMemo;
    JvTimer1: TJvTimer;
    Procedure Button1Click(Sender: TObject);
    Procedure JvTimer1Timer(Sender: TObject);
  Private
    { Déclarations privées }
  Public
    { Déclarations publiques }
  End;

  TMyThread = Class(TThread)
  Protected
    Procedure Execute; Override;
    Destructor destroy; Override;
  End;

Var
  Form1: TForm1;
  Err  : String = '';

Implementation

{$R *.dfm}

Procedure TForm1.Button1Click(Sender: TObject);
Var
  i: integer;
Begin
  For i := 0 To 49 Do
    // For i := 0 To 3 Do
    TMyThread.Create(False);

End;

Var
  NuTh: integer = 0;

  { TMyThread }

Destructor TMyThread.destroy;
Begin
  Inherited;
End;

Procedure TMyThread.Execute;
Var
  Query         : TUIBQuery;
  Transaction   : TUIBTransaction;
  S1            : String;
  NuLect, MyNuTh: integer;
Begin
  FreeOnTerminate := True;
  inc(NuTh);
  MyNuTh := NuTh;
  // Form1.DataBase.Lock; //simulate single thread
  Try
    NuLect      := 0;
    Query       := TUIBQuery.Create(Nil);
    Transaction := TUIBTransaction.Create(Nil);
    Try
      Transaction.DataBase := Form1.DataBase;
      Query.Transaction    := Transaction;
      Query.FetchBlobs     := True;
      Query.SQL.Text       := 'select * from poste';
      Query.Open;
      While Not Query.EOF Do
      Begin
        inc(NuLect);
        S1 := Query.Fields.ByNameAsString['cod_poste'];
        Query.Next;
        sleep(10); // simulate activity
      End;

    Except
      On Erreur: Exception Do
      Begin
        Err := '** Thread=' + IntToStr(MyNuTh) + ' NuLect=' + IntToStr(NuLect) + ' // ' + Erreur.Message;
      End;
    End;

  Finally
    Query.Close(etmCommit);
    Query.Free;
    Transaction.Free;
    // Form1.DataBase.UnLock; //simulate single thread
  End;
End;

Procedure TForm1.JvTimer1Timer(Sender: TObject);
Begin
  If Err <> '' Then
  Begin
    JvMemo1.Lines.Add(Err);
    Err := '';
  End;
End;

End.
J'ai testé ce même code sur mon ancien environnement D2007 (en changeant juste les TUibxx par TJvUibxx) et tout fonctionne très bien.
Cela peut-il venir de la compatibilité UIB25 avec DXE2 ?
De mon installation des composants UIB 2.5 ? (j'ai juste modifié le uib.inc pour choisir la version FB)
Avez vous la possibilité de tester ce petit prog dans un environement DXE2/UIB25 (adaptez juste les parties rouges) ?
Merci de votre aide , je boucle la dessus depuis plusieurs jours !
jml.
Aegir est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2012, 15h11   #2
Expert Confirmé

 
Homme Philippe Makowski
Consultant spécialité Firebird
Inscription : mai 2002
Messages : 2 215
Détails du profil
Informations personnelles :
Nom : Homme Philippe Makowski
Âge : 49
Localisation : France

Informations professionnelles :
Activité : Consultant spécialité Firebird
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 2 215
Points : 3 318
Points : 3 318
vous utilisez bien la dernière version des uib ?
c'est à dire un check out du dépot subversion ?
__________________
Philippe Makowski
IBPhoenix - Firebird
Membre de l'April
makowski est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2012, 19h31   #3
Invité de passage
 
Homme Jean-Marie
Développeur informatique
Inscription : février 2012
Messages : 5
Détails du profil
Informations personnelles :
Nom : Homme Jean-Marie
Localisation : France, Aube (Champagne Ardenne)

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2012
Messages : 5
Points : 0
Points : 0
Bonjour,
Cette version date du 11/10/2010, c'est la plus récente que j'ai trouvée.
ici: http://sourceforge.net/projects/uib/files/
à cette date DXE2 n'était pas sorti il me semble ...

J'ai installé cettte UIB 2.5 sur D2007 et j'ai des problèmes similaires avec ceux sur DXE2 (violations d'accès principalement, rarement les mêmes).

Dans UIB 2.1 il y avait une directive UIBTHREADSAFE, elle semble avoir disparu dans la version 2.5.

Je tente maintenant de réinstaller UIB 2.1 sur DXE2.

Merci pour ton aide.
Jml
Aegir est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/02/2012, 09h19   #4
Modérateur
 
Avatar de SergioMaster
 
Serge Girard
Développeur informatique
Inscription : janvier 2007
Messages : 3 627
Détails du profil
Informations personnelles :
Nom : Serge Girard
Âge : 55
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : Industrie

Informations forums :
Inscription : janvier 2007
Messages : 3 627
Points : 4 532
Points : 4 532
Citation:
Envoyé par Aegir Voir le message
Cette version date du 11/10/2010, c'est la plus récente que j'ai trouvée.
ici: http://sourceforge.net/projects/uib/files/
Ceci est la dernière version téléchargeable , cependant il est conseillé d'utiliser la version Mise en Dépôt SVN comme l'indique makowski

Voir ici
__________________
La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein
J'entends et j'oublie. Je vois et je me souviens. Je fais et je comprends . Confucius
SergioMaster est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/02/2012, 13h41   #5
Invité de passage
 
Homme Jean-Marie
Développeur informatique
Inscription : février 2012
Messages : 5
Détails du profil
Informations personnelles :
Nom : Homme Jean-Marie
Localisation : France, Aube (Champagne Ardenne)

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2012
Messages : 5
Points : 0
Points : 0
Bonjour,
J'ai suivi vos conseils.
Purge de tous les paquets UIB installés dans delphi.
Purge de tous les fichiers UIB téléchargés précédement
Installation de Tortoise
Check out avec l'adresse https://uib.svn.sourceforge.net/svnroot/uib/trunk
Nouveautés visibles dans cette version: Un paquet D16 et FB 3.0
Modif de uib.inc pour mettre {$DEFINE FB21}
Installation des Paquets dans DXE2 en Win32 => pas de problème
Le programe de test MultiThread ne fonctionne pas mieux, même type d'erreurs !
J'utilise fbclient.dll livrée avec FB 2.1
Je précise que ce programme de test fonctionne très bien avec UIB 2.1 sous D2007 et que même installé sous D2007, UIB 2.5 ne fonctionne plus.
J'ai tenté l'instalation de UIB 2.1 sur DXE2 mais cela ne compile évidemment pas.
La question que je me pose est : la version 2.5 est-elle bien multi-thread ?
N'y aurait-il pas un $DEFINE à mettre quelque part ?

PS: je serais vraiment curieux de savoir si ce prog de test fonctionne chez vous en version 2.5 (apparemment la version Delphi importe peu)

jml
Aegir est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2012, 07h46   #6
Modérateur
 
Avatar de SergioMaster
 
Serge Girard
Développeur informatique
Inscription : janvier 2007
Messages : 3 627
Détails du profil
Informations personnelles :
Nom : Serge Girard
Âge : 55
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : Industrie

Informations forums :
Inscription : janvier 2007
Messages : 3 627
Points : 4 532
Points : 4 532
Citation:
je serais vraiment curieux de savoir si ce prog de test fonctionne chez vous en version 2.5 (apparemment la version Delphi importe peu)
Désolé , j'en suis encore qu'a la 2.1 pour des raisons d'exploitation trop longues a expliquer et j'attends toujours que XE propose une compilation LINUX pour passer le pas .
Le mieux (si ce n'est déjà fait) serait peut être d'aller voir sur le forum de prodigy ?
__________________
La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein
J'entends et j'oublie. Je vois et je me souviens. Je fais et je comprends . Confucius
SergioMaster est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2012, 16h44   #7
Invité de passage
 
Homme Jean-Marie
Développeur informatique
Inscription : février 2012
Messages : 5
Détails du profil
Informations personnelles :
Nom : Homme Jean-Marie
Localisation : France, Aube (Champagne Ardenne)

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2012
Messages : 5
Points : 0
Points : 0
Bonjour,
Toujours aucune solution ...
J'envisage les voies suivantes :
* Tenter de porter UIB 2.1 sur DXE2
* Reporter le portage de mon application sur DXE2 en gardant un compatibilité des sources D2007/DXE2 (en attendant un UIB 2.6 ...)
* Envisager d'autres solutions comme FibPlus et consorts
J'ai expliqué mon problème sur le forum Progdigy, on verra bien.
J'ai un peu de mal à imaginer être le seul à être tombé la dessus ou alors tout le monde est resté en 2.1 comme toi.
Je n'ai pas trouvé de version 2.2, 2.3, 2.4, normal ?
JML
Aegir est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2012, 18h19   #8
Invité de passage
 
Homme Jean-Marie
Développeur informatique
Inscription : février 2012
Messages : 5
Détails du profil
Informations personnelles :
Nom : Homme Jean-Marie
Localisation : France, Aube (Champagne Ardenne)

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2012
Messages : 5
Points : 0
Points : 0
Bonjour,
N'ayant aucune réponse ni explication sur ce phénomène, j'ai décidé d'explorer une autre voie.
Suite à différents tests, je me suis aperçu que ce n'était pas le fait que les appels UIB se faisaient dans un Thread mais plutôt à cause du parallélisme engendré.
J'ai donc entouré tous les appels UIB par des sections critiques.
Depuis, plus aucun problème dans le prog. de test. J'ai appliqué cette même méthode dans mon application ce qui m'a permis de retrouver enfin un fonctionnement stable.
Ci-dessous le prog. de test modifié.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
 
Unit main;
 
Interface
 
Uses
{$IFDEF LINUX}
  libc, QForms, QStdCtrls, QControls, QGraphics, QDialogs, QExtCtrls,
{$ELSE}
  Windows, Graphics, Controls, Forms, Messages, Dialogs, StdCtrls,
{$ENDIF}
  SysUtils, Classes, uib, SyncObjs, JvTimer, JvExStdCtrls, JvMemo, JvEdit, JvValidateEdit, JmEdit; // , JvTimer, JvExStdCtrls, JvMemo; // , JvExStdCtrls, JvMemo, JvTimer;
 
{$DEFINE WITH_THREAD}
 
Type
  TForm1 = Class(TForm)
    DATABASE: TUIBDataBase;
    Button1: TButton;
    JvMemo1: TJvMemo;
    JvTimer1: TJvTimer;
    JmEdit1: TJmEdit;
    Procedure Button1Click(Sender: TObject);
    Procedure JvTimer1Timer(Sender: TObject);
  Private
    { Déclarations privées }
  Public
    { Déclarations publiques }
  End;
 
  TMyThread = Class(TThread)
  Protected
    TheEnd: BOOLEAN;
{$IFDEF WITH_THREAD}
    Procedure Execute; Override;
{$ENDIF}
    Destructor destroy; Override;
  End;
 
Var
  Form1          : TForm1;
  Err            : String = '';
  Info           : String = '';
//  MutexUib       : THandle;
  CriticalSection: TRTLCriticalSection;
 
Implementation
 
{$R *.dfm}
 
Var
  NuTh: integer = 0;
 
  { TMyThread }
 
Destructor TMyThread.destroy;
Begin
  Inherited;
End;
 
{$IFDEF WITH_THREAD}
 
Procedure TMyThread.Execute;
{$ELSE}
 
Procedure Execute;
{$ENDIF}
Var
  Query         : TUIBQuery;
  Transaction   : TUIBTransaction;
  S1, Etape     : String;
  NuLect, MyNuTh: integer;
Begin
{$IFDEF WITH_THREAD}
  FreeOnTerminate := True;
{$ENDIF}
  TheEnd := False;
  inc(NuTh);
  MyNuTh := NuTh;
  // Form1.DATABASE.LOCK; //simulate single thread
  Try
    Etape       := 'Create Transac & Query';
    NuLect      := 0;
    Query       := TUIBQuery.CREATE(Nil);
    Transaction := TUIBTransaction.CREATE(Nil);
    Try
 
      Transaction.DATABASE := Form1.DATABASE;
      Query.Transaction    := Transaction;
      Query.FetchBlobs     := True;
      Query.SQL.Text       := 'select * from poste';
      // Query.SQL.Text := 'select * from project';
 
      // WaitForSingleObject(MutexUib, INFINITE);
      EnterCriticalSection(CriticalSection);
      Etape := 'Query.open';
      Err  := '** Thread=' + IntToStr(MyNuTh) + '  NuLect=' + IntToStr(NuLect) + '  Etape=' + Etape;
      Query.Open;
      sleep(10); // simulate activity
      // ReleaseMutex(MutexUib);
      LeaveCriticalSection(CriticalSection);
 
      While NOT Query.EOF Do
      Begin
        inc(NuLect);
        Etape := 'Query.Fields.ByNameAsString';
        S1    := Query.FIELDS.ByNameAsString['cod_poste'];
        // WaitForSingleObject(MutexUib, INFINITE);
        EnterCriticalSection(CriticalSection);
        Etape := 'Query.Next';
        Query.Next;
        // ReleaseMutex(MutexUib);
//        Err := '** Thread=' + IntToStr(MyNuTh) + '  NuLect=' + IntToStr(NuLect) + '  Etape=' + Etape;
        LeaveCriticalSection(CriticalSection);
        sleep(1); // simulate activity
      End;
    Except
      ON Erreur: Exception Do
      Begin
        Err := '** Thread=' + IntToStr(MyNuTh) + '  NuLect=' + IntToStr(NuLect) + '  Etape=' + Etape + '  Except=' + Erreur.Message;
      End;
    End;
  Finally
 
    EnterCriticalSection(CriticalSection);
//    WaitForSingleObject(MutexUib, INFINITE);
    Etape := 'Query.Close';
    Err  := '** Thread=' + IntToStr(MyNuTh) + '  NuLect=' + IntToStr(NuLect) + '  Etape=' + Etape;
    // Form1.JvMemo1.LINES.ADD(Info);
    Query.Close(etmCommit);
    sleep(10); // simulate activity
    // ReleaseMutex(MutexUib);
    LeaveCriticalSection(CriticalSection);
 
    Query.Free;
    Transaction.Free;
    // Form1.DATABASE.UNLOCK; //simulate single thread
  End;
  TheEnd := True;
End;
 
Procedure TForm1.JvTimer1Timer(Sender: TObject);
Begin
  JvTimer1.Enabled := False;
  IF Err <> '' Then
  Begin
    JvMemo1.LINES.ADD('**** ' + Err);
    Err := '';
  End;
  // IF Info <> '' Then
  // Begin
  // JvMemo1.LINES.ADD(Info);
  // Info := '';
  // End;
  JvTimer1.Enabled := True;
End;
 
Procedure TForm1.Button1Click(Sender: TObject);
Var
  i        : integer;
  MonThread: TMyThread;
  TickStart: Int64;
Begin
 
  TickStart := GetTickcount;
  FOR i     := 0 TO 49 Do
  // FOR i := 0 TO 9 Do
  Begin
    JvMemo1.LINES.ADD('=========> Lancement ' + IntToStr(i));
{$IFDEF WITH_THREAD}
    MonThread        := TMyThread.CREATE(False);
    MonThread.TheEnd := False;
    // While NOT(MonThread.TheEnd) Do
    // Begin
    // Application.ProcessMessages;
    // End;
{$ELSE}
    Execute;
{$ENDIF}
  End;
  JvMemo1.LINES.ADD('=========> FIN');
End;
 
Initialization
 
//MutexUib := CreateMutex(Nil, False, 'MutexUib');
InitializeCriticalSection(CriticalSection);
 
End.
Aegir est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/03/2012, 13h25   #9
Invité régulier
 
Homme DEV DELPHI
Étudiant
Inscription : février 2012
Messages : 11
Détails du profil
Informations personnelles :
Nom : Homme DEV DELPHI
Localisation : Tunisie

Informations professionnelles :
Activité : Étudiant
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2012
Messages : 11
Points : 7
Points : 7
Je pense que ceci répond à ton souci :

Multithreading and N-Tiers servers application.
You have 2 choices:

-Sharing one DB connection with all threads, in this case 2 threads can share the same Database connection or the same Transaction safely without freezing the server. Some examples of server applications are: Web server, CORBA, DCOM, or Delphi ORB provided provided with UIB. For an example of Multithread server try the the sample applications in the "ClentServer" directory. You must set this compiler option: {$DEFINE UIBTHREADSAFE} excepting with Interbase 7 (The library is allready ThreadSafe)

-Create one DB Connection per Thread, in this case you should desactivate {$DEFINE UIBTHREADSAFE}, and setting your DB connection to use the remote protocol (excepting with Interbase 7), to have all threads working faster.



il faut créer dynamiquement autant de DB Connection que de threads. Comme ça tu aura la tête tranquille
dietrying est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/03/2012, 06h51   #10
Modérateur
 
Avatar de SergioMaster
 
Serge Girard
Développeur informatique
Inscription : janvier 2007
Messages : 3 627
Détails du profil
Informations personnelles :
Nom : Serge Girard
Âge : 55
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : Industrie

Informations forums :
Inscription : janvier 2007
Messages : 3 627
Points : 4 532
Points : 4 532
Citation:
Envoyé par Aegir Voir le message
J'ai un peu de mal à imaginer être le seul à être tombé la dessus ou alors tout le monde est resté en 2.1 comme toi.
Je n'ai pas trouvé de version 2.2, 2.3, 2.4, normal ?
JML
Pas de version 2.2,2.3 etc... oui , normal je crois même qu'il y a un explication a cette numérotation indiquée quelque part (notes de version 2.5 je crois)

Quant au multithread alors là aucune idée
__________________
La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein
J'entends et j'oublie. Je vois et je me souviens. Je fais et je comprends . Confucius
SergioMaster est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/03/2012, 14h31   #11
Invité régulier
 
Homme DEV DELPHI
Étudiant
Inscription : février 2012
Messages : 11
Détails du profil
Informations personnelles :
Nom : Homme DEV DELPHI
Localisation : Tunisie

Informations professionnelles :
Activité : Étudiant
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2012
Messages : 11
Points : 7
Points : 7
Tu peux te base sur l'exemple multithread fourni avec IBOJECTS.

L’instanciation du module de données se fait dans un SUB-THREAD dans une section critique

Alors tu déclare une variable comme suit :

Code :
1
2
var
  CSCreateDestroyDM: TRTLCriticalSection;

Et puis tu dois créer un module de données par exemple nomé dmthreads comme suit :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
procedure TMyThread.Execute;
begin
  try
EnterCriticalSection(CSCreateDestroyDM);
    try
      dmThreads := TdmThreads.CREATE( nil );
    finally
      LeaveCriticalSection(CSCreateDestroyDM);
    end;
// ici tu définis les paramètres de connexion à la base TUIBDATABASE
// tu synchronise aussi avec l'interface

dans le module dmthreads tu ajoute TIUBDATABASE, TUIBTRASACTION,....

tu dois essayé. Pour moi ça marche bien avec 150 threads
dietrying est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h55.


 
 
 
 
Partenaires

Hébergement Web