Usage of PGAlerter, Threads etc

Discussion of open issues, suggestions and bugs regarding PgDAC (PostgreSQL Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
dschuch
Posts: 75
Joined: Thu 05 Feb 2009 15:29
Location: Dresden

Usage of PGAlerter, Threads etc

Post by dschuch » Wed 29 Aug 2012 10:17

Hi, currently we have some trouble in our Application with ACCESS VIOALTIONS. This is a new effect. We implemented PGAlerter-Functionality some weeks ago. Also - Eurekalog shows us that the PGAlerter Thread is included in some exceptions.

Some fundamental questions:

I think pgAlerter itsself is threadsave. Its using the same connection as the MainThread of the application. (Or does it need a own Connection?) (Example: User 1 is calling a huge query, user 2 calls a Notification for user 1/User 1 is registered to recieve - at this time)

Is the OnEvent (OnNotification) is syncronized with the MainThread? If i do "MessageBox", etc? (Or do we need to Syncronize the MainThread for Painting issues and so on ourself)

Its a bit confusing that in some of the logs i see procedures/lines that doesnt have a relation to your PGAlerter (e.g. a CalcFields Exception).

It does not seem that the OnEvent Event is called. There was no Notification on the Backend at this time.

Perhaps you can give us some hints on what we should look for, or what we need to do, to handle Multi Threads with PGAlerter.


Here some Log Information: (copy and insert into notepad because of fixed fonts, you see the formated text very well there. See Line 7)

Code: Select all

|------------------------------------------------------------------------------------------------------------|
|                                                                                                            |
|Running Thread: ID=1984; Priority=0; Class=TPgSQLNotificationsThread                                        |
|------------------------------------------------------------------------------------------------------------|
|7C91DF58|ntdll.dll     |                     |                          |NtWaitForSingleObject      |       |
|5003D7CC|rtl150.bpl    |System.pas           |                          |_UStrCatN                  |       |
|01CD85A0|SysWAWIXE.bpl |ClassLager.pas       |TWarenEingangsschein      |_CalcFields                |785[7] |
|7C91D2A8|ntdll.dll     |                     |                          |NtDuplicateObject          |       |
|7C80DEFD|kernel32.dll  |                     |                          |DuplicateHandle            |       |
|7C80DF0E|kernel32.dll  |                     |                          |DuplicateHandle            |       |
|71A0150A|WS2HELP.dll   |                     |                          |WahReferenceContextByHandle|       |
|71A130A8|WS2_32.dll    |                     |                          |select                     |       |
|71A14D1A|WS2_32.dll    |                     |                          |WSARecv                    |       |
|71A14CB5|WS2_32.dll    |                     |                          |WSARecv                    |       |
|71A32E9E|wsock32.dll   |                     |                          |recv                       |       |
|7C91DF48|ntdll.dll     |                     |                          |ZwWaitForMultipleObjects   |       |
|7C91DF58|ntdll.dll     |                     |                          |NtWaitForSingleObject      |       |
|7C91DF4E|ntdll.dll     |                     |                          |NtWaitForSingleObject      |       |
|7C929B1E|ntdll.dll     |                     |                          |RtlpWaitForCriticalSection |       |
|0034A6D2|pgdac150.bpl  |Pgsqlprotocol.pas    |TPgSQLProtocol            |ProcessMessageQueue        |       |
|0034A658|pgdac150.bpl  |Pgsqlprotocol.pas    |TPgSQLProtocol            |ProcessMessageQueue        |       |
|00375172|pgdac150.bpl  |Pgclasses.pas        |TPgSQLNotificationsThread |Execute                    |       |
|50037581|rtl150.bpl    |System.pas           |                          |_ReallocMem                |       |
|------------------------------------------------------------------------------------------------------------|
|Calling Thread: ID=216; Priority=0; Class=; [Main]                                                          |
|------------------------------------------------------------------------------------------------------------|
|500ADA50|rtl150.bpl    |Classes.pas          |TThread                   |Resume                     |       |
|500ADA48|rtl150.bpl    |Classes.pas          |TThread                   |Resume                     |       |
|00374DA8|pgdac150.bpl  |Pgclasses.pas        |TPgSQLNotificationsHandler|EventIndex                 |       |
|00374EA7|pgdac150.bpl  |Pgclasses.pas        |TPgSQLNotificationsHandler|Listen                     |       |
|00374E80|pgdac150.bpl  |Pgclasses.pas        |TPgSQLNotificationsHandler|Listen                     |       |
|00374928|pgdac150.bpl  |Pgclasses.pas        |TPgSQLNotificationsHandler|RegisterEvents             |       |
|00374526|pgdac150.bpl  |Pgclasses.pas        |TPgSQLAlerter             |Start                      |       |
|0071E7A9|dac150.bpl    |Daalerter.pas        |TDAAlerter                |Start                      |       |
|0071E724|dac150.bpl    |Daalerter.pas        |TDAAlerter                |Start                      |       |
|0071EE88|dac150.bpl    |Daalerter.pas        |TDAAlerter                |SetActive                  |       |
|007A081C|SysDBXE.bpl   |UCimNotifications.pas|TCimNotify                |Connect                    |65[4]  |
|007A07C0|SysDBXE.bpl   |UCimNotifications.pas|TCimNotify                |Connect                    |61[0]  |
|007AAE09|SysDBXE.bpl   |udm1.pas             |TDM1                      |DataBase1AfterConnect      |494[13]|
|006E3EB0|dac150.bpl    |Dbaccess.pas         |TCustomDAConnection       |Disconnect                 |       |
|00793468|SysDBXE.bpl   |UDataModul_SysDB.pas |TCimDM_SysDB              |SetStartScreenStatus       |134[2] |
|006E3EA4|dac150.bpl    |Dbaccess.pas         |TCustomDAConnection       |Connect                    |       |
|006E3EA0|dac150.bpl    |Dbaccess.pas         |TCustomDAConnection       |Connect                    |       |
|007AF090|SysDBXE.bpl   |udm1.pas             |TDM1                      |Connect                    |1422[6]|
|007AF080|SysDBXE.bpl   |udm1.pas             |TDM1                      |Connect                    |1416[0]|
|004B047F|ProdatSQL.exe |UHauptForm.pas       |THauptForm                |OpenDatabaseExecute        |748[70]|
|004AFD50|ProdatSQL.exe |UHauptForm.pas       |THauptForm                |OpenDatabaseExecute        |678[0] |
|004B305C|ProdatSQL.exe |UHauptForm.pas       |THauptForm                |LoginTimerTimer            |1265[4]|
|502D2EC3|vcl150.bpl    |Extctrls.pas         |TTimer                    |Timer                      |       |
|5003A47C|rtl150.bpl    |System.pas           |                          |_CallDynaInst              |       |
|502D2DA7|vcl150.bpl    |Extctrls.pas         |TTimer                    |WndProc                    |       |
|7E368A0B|USER32.dll    |                     |                          |DispatchMessageW           |       |
|7E368A01|USER32.dll    |                     |                          |DispatchMessageW           |       |
|50358A04|vcl150.bpl    |Forms.pas            |TApplication              |ProcessMessage             |       |
|50358B3A|vcl150.bpl    |Forms.pas            |TApplication              |HandleMessage              |       |
|50358B30|vcl150.bpl    |Forms.pas            |TApplication              |ProcessMessages            |       |
|50358D9C|vcl150.bpl    |Forms.pas            |TApplication              |Run                        |       |
|004C6EFC|ProdatSQL.exe |ProdatSQL.dpr        |                          |                           |45[7]  |
--------------------------------------------------------------------------------------------------------------

AlexP
Devart Team
Posts: 5530
Joined: Tue 10 Aug 2010 11:35

Re: Usage of PGAlerter, Threads etc

Post by AlexP » Thu 30 Aug 2012 12:11

Hello,

A separate thread is created for TPgAlerter for processing message sequence, but, since a "heavy" query runs in the main thread of the application, the onEvent event will be executed only after such query finishes (it will be executed as many times, as there were messages sent).
For executing this event even during a heavy query is running, you should run this query in a separate thread. There is a small sample below, in which a query is running in a separate thread, and during its running the application continues reacting on the onEvent event

Code: Select all

TMyThread = class(TThread)
  public
    procedure execute; override;
  end;

  TForm1 = class(TForm)
    PgConnection1: TPgConnection;
    PgAlerter1: TPgAlerter;
    PgQuery1: TPgQuery;
    Button1: TButton;
    procedure PgAlerter1Event(Sender: TObject; const EventName: String;
      PID: Integer; const EventMessage: String);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.PgAlerter1Event(Sender: TObject; const EventName: String;
  PID: Integer; const EventMessage: String);
begin
  ShowMessage(EventName);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  thread: TMyThread;
begin
  thread := TMyThread.Create(true);
  thread.Resume;
end;

{ TMyThread }

procedure TMyThread.execute;
begin
  Form1.PgQuery1.Open;
  ShowMessage('Open');
  Form1.PgQuery1.Open;
end;

Post Reply