MaximG wrote: ↑Fri 10 Jul 2020 16:21
What features of Advanced Queueing are you going to use? Our components don't offer a dedicated option for enabling or disabling Direct Mode for Advanced Queueing.
Sorry, I don't know how to answer that question. ;-) I just want that the ODAC components work, nothing more nothing less. In the meantime me managed to connect to the database and successfully ENQUEUE a message. Now our main problem is, how to dequeue. We are connecting in directe mode.
So we have code:
Code: Select all
function TfrmMainAOS.DequeueFARMS : Boolean;
var
Agents : TQueueAgents;
Agent : TQueueAgent;
QueueMessage : TQueueMessage;
begin
Result := False;
try
Agents := TQueueAgents.Create;
try
Agents.Add.Address := edtLEJQueueTo.Text;
Agent := TQueueAgent.Create;
OraQueue.QueueName := edtLEJQueueTo.Text;
OraQueue.DequeueOptions.WaitTimeout := AQ_NO_WAIT;
OraQueue.DequeueOptions.Navigation := qnNextMessage;
OraQueue.DequeueOptions.DequeueMode := dqmRemove;
try
Agent := TQueueAgent.Create;
try
OraQueue.Listen(Agents, Agent, FLEJTimeOut);
var DequeueOptions: TDequeueOptions := TDequeueOptions.Create;
try
DequeueOptions.DequeueMode := dqmBrowse;
QueueMessage := TQueueMessage.Create;
try
OraQueue.Dequeue(QueueMessage, DequeueOptions);
OraQueueMessage(OraQueue, QueueMessage.MessageId, QueueMessage.MessageProperties);
finally
FreeAndNil(QueueMessage);
end;
finally
FreeAndNil(DequeueOptions);
end;
finally
Agent.Free;
end;
except
on E : System.SysUtils.Exception do
begin
Log.Fatal(Format('OraSession.LastError: [%d]', [OraSession.LastError]));
HandleExceptionPrim(E, E.message, 10, 'TfrmMainAOS.DequeueFARMS');
end;
end;
finally
Agents.Free;
end;
Result := True;
except
on E : System.SysUtils.Exception do begin
Log.Fatal(Format('OraSession.LastError: [%d]', [OraSession.LastError]));
HandleExceptionPrim(E, E.message, 11, 'TfrmMainAOS.DequeueFARMS');
end;
end;
end;
And:
Code: Select all
procedure TfrmMainAOS.OraQueueMessage(Sender: TOraQueue; const MessageId: string;
const MessageProperties: TQueueMessageProperties);
var
ObjectPayload : TOraObject;
FileName : string;
MsgId : string;
PayLoad : string; // Die eigentlichen Nutzdaten
EnqueueTime : TDateTime;
begin
OraQueue.DequeueOptions.MessageId := MessageId;
OraQueue.DequeueOptions.DeliveryMode := qdmPersistentOrBuffered;
OraQueue.DequeueOptions.DequeueCondition := EmptyStr;
EnqueueTime := MessageProperties.EnqueueTime;
Log.Info(Format('MessageProperties.Delay = [%d]', [MessageProperties.Delay]));
if MessageProperties.Delay > AQ_NO_DELAY then begin
MWWait(MessageProperties.Delay * 1000);
end;
case MessageProperties.State of
qmsReady : Log.Info('MessageProperties.State = qmsReady');
qmsWaiting : Log.Info('MessageProperties.State = qmsWaiting');
qmsProcessed : Log.Info('MessageProperties.State = qmsProcessed');
qmsExpired : Log.Info('MessageProperties.State = qmsExpired');
end;
if {(IncSecond(EnqueueTime,MessageProperties.Expiration) <= now) and } (MessageProperties.State = qmsReady) then begin
try
ObjectPayload := TOraObject.Create;
try
memXMLData.Lines.Clear; // das ist ein TMemo auf dem Formular
FileName := Format('%s\FARMS To AM %s.xml', [edtTxtImportUpdateFolder.Text, FormatDateTime('YYYY DD MM - HH NN SS', Now)]);
Log.Info(Format(' Message ID: [%s]', [MessageId]));
Log.Info(Format(' Enqueue Time : [%s]', [FormatDateTime('YYYY DD MM - HH NN SS', EnqueueTime)]));
Log.Info(Format(' Dequeue Attempts : [%s]', [IntToStr(MessageProperties.Attempts)]));
try
var DequeueOptions: TDequeueOptions := TDequeueOptions.Create;
try
DequeueOptions.DequeueMode := dqmRemove; // Es ist standardmäßig beim Create auf dqmRemove gesetzt, hier einfach zum Hinweis
// hier jetzt die richtige Message holen, die über das Event übergeben wurde (MessageId)
MsgId := OraQueue.Dequeue(ObjectPayload, MessageProperties, DequeueOptions);
finally
FreeAndNil(DequeueOptions);
end;
except
on E : System.SysUtils.Exception do begin
Log.Fatal(Format('OraSession.LastError: [%d]', [OraSession.LastError]));
Log.Fatal(Format('OraQueue.Empty [%s]', [E.Message]));
end;
end;
// hier die Daten holen die in der Payload stehen
if ObjectPayload.AttrIsNull['text_lob'] then begin
PayLoad := ObjectPayload.AttrAsString['text_vc']
end else begin
PayLoad := ObjectPayload.AttrAsLob['text_lob'].AsWideString;
end;
Log.Info(Format('DEQUEUE: MsgId: [%s]; Length: [%d]', [MsgId, ObjectPayload.AttrAsInteger['text_len']]));
memXMLData.Lines.Add(PayLoad);
OraQueue.Session.Commit;
Log.Info(Format('OraSession.LastError: [%d]', [OraSession.LastError]));
finally
FreeAndNil(ObjectPayload);
memXMLData.Lines.SaveToFile(FileName);
end;
except
on E : System.SysUtils.Exception do begin
Log.Fatal(Format('OraSession.LastError: [%d]', [OraSession.LastError]));
HandleExceptionPrim(E, E.message, 12, 'TfrmMainAOS.OraQueueMessage');
end;
end;
end else begin
Log.Fatal(Format(' Error message expired -> Message ID: [%d]', [MessageId]));
end;
end;
The big question is, when do I know that the queues is empty? How often do I have to get a record from the queue in OraQueueMessage?
Thanks in advance.