Newsgroups : Borland : borland.public.delphi.internet.winsock : 2008 Feb : Re: Lag in data reurns using TCP_Infeed
| Subject: | Re: Lag in data reurns using TCP_Infeed |
| Posted by: | "Larry Killen" (lkill..@charter.net) |
| Date: | Thu, 7 Feb 2008 22:24:45 |
Oh yeah,
Using D-2006
Indy 10.2.3
"Larry Killen" <lkillen@charter.net> wrote in message
news:47abcab7@newsgroups.borland.com...
>I am in the field at one of my clients and I am tearing my hair out. It
>seems that I am making requests to a scale indicator and their is a
>progressive lag in the returns as the shift runs. A little back drop.
>
> I have a small application whose sole puporse is to poll a GSE/SPX scale
> indicator and capture that the data that is sent back and write it to a
> database. Most of the data is returned as a result of a request GETDATA
> but on occasion, some data is sent. I am able to monitor my requests and
> the return data. At first the data is returned as soon as I call for it
> but after some time, their is a lag of a few seconds and eventually up to
> two hours! I must also tell you that I communicate with the GSE indicator
> via a DCBNet device that converts serial to TCP/IP and TCP/IP to serial.
> The GSE is on the serial side and the PC on teh TCP/IP side.
>
> I poll the GSE every five seconds and set the timer enabled to false.
> I listen for the returns on the thread below and process it in the thread.
> When I recieve data and process it, I restore the timer. After five
> seconds, I do this again. I am doing this with two GSE's on 2 separate
> threads. The infeed data is much simpler to process and does not lag as
> much. The other "Outfeed" devise is far more complicated to process.
>
> I have ticked timed the processes and they run under 20 ms so I can hardly
> believe that this is causing the delay. It would appear that the data is
> buffering up somewhat but where?
>
> When the GSE's quit sending data, that data will still come for up to 2
> hours and be processed? Where is this data coming from? The DCBNet
> devise does have a buffer but I have it set to send the buffer when a 50
> ms idle is detected.
>
> Please advise.
> Larry
>
>
> unit ReadOutfeedGSE;
>
> interface
>
> uses
> Classes, IdTCPConnection, StrUtils;
>
> type
> TReadingOutfeedThread = class(TThread)
> private
> { Private declarations }
> FConn: TIdTCPConnection;
> FBuffer : string;
> protected
> procedure Execute; override;
> public
> procedure AfterConstruction; override;
> constructor Create(AConn: TIdTCPConnection); reintroduce;
> Procedure ProcessData;
> end;
>
> var
> ReadingOutfeedThread: TReadingOutfeedThread = nil;
>
> OUTFEEDRESULTS : string;
>
> implementation
>
> uses Main;
>
> { ReadingOutfeedThread }
>
> procedure TReadingOutfeedThread.AfterConstruction;
> begin
> inherited;
> Resume;
> end;
>
> constructor TReadingOutfeedThread.Create(AConn: TIdTCPConnection);
> begin
> inherited Create(True);
> FConn := AConn;
> end;
>
> procedure TReadingOutfeedThread.Execute;
> begin
> while not Terminated do
> begin
> FConn.IOHandler.WaitFor(chr(2));
> FBuffer := FConn.IOHandler.ReadLn(chr(3));
> ProcessData;
> end;
> end;
>
>
> procedure TReadingOutfeedThread.ProcessData;
> begin
> frmMain.ProcessOutFeedData(FBuffer);
> end;
>
> end.
>
>
> procedure TfrmMain.ProcessOutFeedData( Buffer : string);
> var
> TxID : integer;
> SecondsToGive : Integer;
> RecordDateTime : TDateTime;
> Station, ActiveProdID : Integer;
> IntEmpID : Integer;
> ByPassMode : TByPassStatus;
> i : Integer;
> oActiveShift : Integer;
> oProdWorkDate : TDateTime;
> const
> BaseDateTime = '12/1/2007 12:00 AM';
> CHECKED = 1;
> BYPASSED = 0;
> begin
>
> Station := 0;
> IntEmpID := 0;
> CommaDataOutfeed.Clear;
> CommaDataOutfeed.StrictDelimiter := True;
> CommaDataOutfeed.CommaText := Buffer;
> ProcessData(cdtOutFeed);
> LastOutfeed := Now;
> TxID := StrToInt(CommaDataOutfeed[0]);
> case TxID of
> 11 : Begin //SessionWT
> RecordDateTime := SysUtils.StrToDateTime(CommaDataOutfeed[6]);
>
> If RecordDateTime < StrToDateTime(BaseDateTime) then
> Begin
> DM.insExceptions.Parameters.ParamByName('DateOccurred').Value
> := Now;
> DM.insExceptions.Parameters.ParamByName('Message').Value :=
> SysUtils.StrToDateTime(CommaDataOutfeed[6]+' '+'Outfeed');
> DM.insExceptions.ExecSQL;
> Begin
> exit;
> tmrPollOutData.Enabled := true;
> End;
> End;
>
> try
> DM.spgetshiftproddate.Close;
>
> DM.spgetshiftproddate.Parameters.ParamByName('@CurrentDateTime').Value :=
> RecordDateTime;
> DM.spgetshiftproddate.ExecProc;
> IF
> DM.spgetshiftproddate.Parameters.ParamByName('@RETURN_VALUE').Value = 0
> then
> oActiveShift :=
> DM.spgetshiftproddate.Parameters.ParamByName('@shift').Value
> Else
> oActiveShift := 0;
> oProdWorkDate :=
> DM.spgetshiftproddate.Parameters.ParamByName('@prodworkdate').Value;
> Finally
> DM.spgetshiftproddate.close;
> end;
>
> If StrToFloat(CommaDataOutfeed[5]) < MinOutFeedWt then
> Begin
> DM.insExceptions.Parameters.ParamByName('DateOccurred').Value
> := Now;
> DM.insExceptions.Parameters.ParamByName('Message').Value :=
> 'Sta '+CommaDataOutfeed[4]+
> ' Wt '+CommaDataOutfeed[5]+' '+'Outfeed';
> DM.insExceptions.ExecSQL;
> Begin
> exit;
> tmrPollOutData.Enabled := true;
> End;
> End;
> OutFeedBroadCast := '';
> OutfeedProdID := StrToInt(CommaDataOutfeed[1]);
> For i := 0 to CommaDataOutfeed.Count -1 do
> Begin
> OutFeedBroadCast := OutFeedBroadCast +' '+ CommaDataOutfeed[i];
> End;
> If ShowStream then DisplayOutFeedData;
>
> If LastOutShift <> oActiveShift then
> Begin
> TCP_Outfeed.IOHandler.WriteLn('GATETOTALS'+#13#10);{ TODO : move
> to zero flag }
> LastOutShift := oActiveShift;
> End;
>
> OutFeedBroadCast := 'Active Shift '+ IntToStr(oActiveShift);
> If ShowStream then DisplayOutFeedData;
> Try
> Try
> Begin
> Station := StrToInt(CommaDataOutfeed[4]);
> DM.qryGetIntEmpID.close;
> DM.qryGetIntEmpID.Parameters.ParamByName('Shift').Value :=
> oActiveShift;
> DM.qryGetIntEmpID.Parameters.ParamByName('Station').Value :=
> Station;
> DM.qryGetIntEmpID.Open;
> IntEmpID :=
> DM.qryGetIntEmpID.FieldByName('IntEmpID').AsInteger;
> DM.qryGetIntEmpID.close;
> End;
> Except
> On E:Exception do
> Begin
> OutFeedBroadCast := 'Broke ' + E.Message+' Station '+
> IntToStr(Station)+
> ' ActiveShift '+ IntToStr(oActiveShift)+
> ' IntEmpID '+ IntToStr(IntEmpID);
> If ShowStream then DisplayOutFeedData;
> End;
> End;
>
> With DM.insOutFeed do
> Begin
> Parameters.ParamByName('Station').Value := Station;
> Parameters.ParamByName('Shift').Value := oActiveShift;
> Parameters.ParamByName('IntEmpID').Value := IntEmpID;
> Parameters.ParamByName('Weight').Value :=
> StrToFloat(CommaDataOutfeed[5]);
> Parameters.ParamByName('WeighTime').Value :=
> RecordDateTime;
> Parameters.ParamByName('ProdID').Value := OutfeedProdID;
> Parameters.ParamByName('ProdWorkDate').Value := oProdWorkDate;
> Parameters.ParamByName('BatchSeq').Value :=
> StrToInt(CommaDataOutfeed[7]);
> ExecSQL;
> End;
> except
> on E:Exception do
> Begin
> For i := 0 to CommaDataOutfeed.Count -1 do
> Begin
> OutFeedBroadCast := OutFeedBroadCast +'
> '+CommaDataOutfeed[i];
> End;
> DM.insExceptions.Parameters.ParamByName('DateOccurred').Value
> := Now;
> DM.insExceptions.Parameters.ParamByName('Message').Value :=
> OutFeedBroadCast;
> DM.insExceptions.ExecSQL;
> If ShowStream then DisplayOutFeedData;
> End;
> End; // Try-Except
>
> OutFeedBroadCast := 'Assigned Outfeed to DB for Shift
> '+IntToStr(ActiveShift);
> If ShowStream then DisplayOutFeedData;
> End;
> 12 : Begin //NODATA%e
> OutFeedBroadCast := '';
> For i := 0 to CommaDataOutfeed.Count -1 do
> Begin { TODO 1 -oLarry -cNext Release : update shift and
> prodworkdate }
> OutFeedBroadCast := OutFeedBroadCast +' '+CommaDataOutfeed[i];
> End;
> If ShowStream then DisplayOutFeedData;
> End;
> 13 : Begin //RESETTOTALS%e;
> For i := 0 to CommaDataOutfeed.Count -1 do
> Begin
> OutFeedBroadCast := OutFeedBroadCast +' '+CommaDataOutfeed[i];
> End;
> If ShowStream then DisplayOutFeedData;
> {At End of Shift. Store to totals table}
> End;
> 15 : Begin //ZEROFLAG%e
> For i := 0 to CommaDataOutfeed.Count -1 do
> Begin
> OutFeedBroadCast := OutFeedBroadCast +' '+CommaDataOutfeed[i];
> End;
> If ShowStream then DisplayOutFeedData;
>
> try { TODO 1 -oLarry -cNext Release : remove after adding to
> infeed trigger }
> DM.spgetshiftproddate.Close;
>
> DM.spgetshiftproddate.Parameters.ParamByName('@CurrentDateTime').Value :=
> now;
> DM.spgetshiftproddate.ExecProc;
> ActiveShift :=
> DM.spgetshiftproddate.Parameters.ParamByName('@shift').Value;
> ProdWorkDate :=
> DM.spgetshiftproddate.Parameters.ParamByName('@prodworkdate').Value;
> Finally
> DM.spgetshiftproddate.close;
> end;
>
> SetTimeAllGSE;
> OutFeedBroadCast := 'Synching ALL GSE times';
> If ShowStream then DisplayOutFeedData;
>
> NewZeroFlag := Now;
> OutFeedBroadCast := 'Recording Zero Flag Time';
> If ShowStream then DisplayOutFeedData;
>
> SecondsToGive := ABS(SecondsBetween(LastZeroFlag, NewZeroFlag));
> OutFeedBroadCast := 'Seconds to give '+IntToStr(SecondsToGive);
> If ShowStream then DisplayOutFeedData;
>
> If SecondsToGive < 600 then
> Begin
>
> dm.spIncrementAccumulator.Parameters.ParamByName('@Shift').Value :=
> ActiveShift;
>
> dm.spIncrementAccumulator.Parameters.ParamByName('@Seconds').Value :=
> SecondsToGive;
>
> dm.spIncrementAccumulator.Parameters.ParamByName('@ProdWorkDate').Value :=
> ProdWorkDate;
>
> dm.spIncrementAccumulator.Parameters.ParamByName('@ProdID').Value :=
> OutfeedProdID;
> dm.spIncrementAccumulator.ExecProc;
> End;
>
> // Update Station_Worker from Staged_Station_Worker
> Begin
> dm.spPushStagedWorker.Parameters.ParamByName('@Shift').Value :=
> ActiveShift;
> dm.spPushStagedWorker.ExecProc;
> End;
> OutFeedBroadCast := 'Updating StationWorker from Staging';
> If ShowStream then DisplayOutFeedData;
> LastZeroFlag := NewZeroFlag;
>
> // Update Infeed to Status of all stations
> Try { TODO 1 -oLarry -cNext Release : Must use real time shift.
> Look at ZeroActive Shift. }
> StationsStatus := '';
> DM.qryGetStationStatus.Close;
> DM.qryGetStationStatus.Parameters.ParamByName('Shift').Value :=
> ActiveShift;
> DM.qryGetStationStatus.Open;
> DM.qryGetStationStatus.First;
> While not(DM.qryGetStationStatus.Eof) do
> Begin
> // Build string to send station status
> StationsStatus := (StationsStatus + 'G' +
> DM.qryGetStationStatus.FieldByName('Station').AsString +
> DM.qryGetStationStatus.FieldByName('StationOn').AsString);
> DM.qryGetStationStatus.Next;
> End;
>
> TCP_Infeed.IOHandler.WriteLn(StationsStatus + #13#10);
>
> Finally
> DM.qryGetStationStatus.Close;
> End;
> OutFeedBroadCast := 'Updating Station status for Infeed as
> :'+StationsStatus;
> If ShowStream then DisplayOutFeedData;
>
> //Pull in settings table
> try
> DM.qryGetSettings.open;
> RandomByPassCount :=
> DM.qryGetSettings.FieldByName('RandomByPassCount').AsInteger;
> FixedCountDesired :=
> DM.qryGetSettings.FieldByName('FixedCountDesired').AsInteger;
> ForcedCount :=
> DM.qryGetSettings.FieldByName('ForcedCount').AsInteger;
> BypassCount :=
> DM.qryGetSettings.FieldByName('BypassCount').AsInteger;
> MinScore := DM.qryGetSettings.FieldByName('MinScore').AsInteger;
> ByPassMode :=
> TByPassStatus(DM.qryGetSettings.FieldByName('ByPassMode').AsInteger);
> StationCount :=
> DM.qryGetSettings.FieldByName('StationCount').AsInteger;
> QCcalcTime :=
> DM.qryGetSettings.FieldByName('QCTimeOutComp').AsBoolean;
> ActiveProdID :=
> DM.qryGetSettings.FieldByName('ActiveProdID').AsInteger;
> finally
> DM.qryGetSettings.close;
> end;
>
> //Process Product ID
> Begin // send the active product ID
> If TCP_Infeed.Connected = true then
>
> TCP_Infeed.IOHandler.WriteLn('PRODID'+IntToStr(ActiveProdID)+#13#10);
> InFeedBroadCast := 'Sent ProdID';
> If ShowStream then DisplayInFeedData;
>
> If TCP_Outfeed.Connected = true then
>
> TCP_Outfeed.IOHandler.WriteLn('PRODID'+IntToStr(ActiveProdID)+#13#10);
> OutFeedBroadCast := 'Sent ProdID';
> If ShowStream then DisplayOutFeedData;
> End;
>
>
> Case ByPassMode of
> bpNone : Begin //QC all 0
>
> DM.updAllByPassStatus.Parameters.ParamByName('BypassStatus').Value :=
> CHECKED;
>
> DM.updAllByPassStatus.Parameters.ParamByName('Shift').Value :=
> ActiveShift;
> DM.updAllByPassStatus.ExecSQL;
> OutFeedBroadCast := 'Processing BPMode None';
> If ShowStream then DisplayOutFeedData;
> End;
> bpFull : Begin //QC None 1
>
> DM.updAllByPassStatus.Parameters.ParamByName('BypassStatus').Value :=
> BYPASSED;
>
> DM.updAllByPassStatus.Parameters.ParamByName('Shift').Value :=
> ActiveShift;
> DM.updAllByPassStatus.ExecSQL;
> OutFeedBroadCast := 'Processing BPMode ALL';
> If ShowStream then DisplayOutFeedData;
> End;
> bpRandom : Begin //Random 2
> SetRandomBypass;
> // Set QCTimeOut value 8 X RandomByPassCount
> OutFeedBroadCast := 'SetRandomBypass';
> If ShowStream then DisplayOutFeedData;
> End;
> bpFixedCount : Begin //Fixed Count 3
> SetMeritSystemBypass(bpFixedCount);
> OutFeedBroadCast := ' Fixed Count Bypass Set';
> If ShowStream then DisplayOutFeedData;
> End;
> bpMinScore : Begin //Min Score 4
> SetMeritSystemBypass(bpMinScore);
> OutFeedBroadCast := ' Min Score Bypass Set';
> If ShowStream then DisplayOutFeedData;
> End;
>
> End;
>
> SendOutFeedBypassState;
> IF QCcalcTime then
> Begin
> DM.upDateQCTimeOut.Parameters.ParamByName('QCTimeOut').Value :=
> QCTimeOut;
> DM.upDateQCTimeOut.ExecSQL;
> OutFeedBroadCast := 'QC Timeout is ' +IntToStr(QCTimeOut);
> If ShowStream then DisplayOutFeedData;
> End;
>
> OutFeedBroadCast:= 'Send OutFeed Stations to Bypass
> '+BypassStatus;
> If ShowStream then DisplayOutFeedData;
>
> OutFeedBroadCast := ' Processed Zero Flag
> Complete'+DateTimeToStr(Now);
> If ShowStream then DisplayOutFeedData;
> End; //ZEROFLAG%e
> 50 : Begin //GateTotals
> If ProcessNewShiftOutfeed then
> Begin
> TCP_Outfeed.IOHandler.WriteLn('RESETTOTALS'+#13#10);
> OutFeedBroadCast := 'RESETTOTALS ';
> For i := 0 to CommaDataOutfeed.Count -1 do
> Begin
> OutFeedBroadCast := OutFeedBroadCast +'
> '+CommaDataOutfeed[i];
> End;
> If ShowStream then DisplayOutFeedData;
> End;
> End; //GateTotals
> 59 : Begin //BypassStatus
> OutFeedBroadCast := 'Bypass Status ';
> For i := 0 to CommaDataOutfeed.Count -1 do
> Begin
> OutFeedBroadCast := OutFeedBroadCast +' '+CommaDataOutfeed[i];
> End;
> If ShowStream then DisplayOutFeedData;
> End; //BypassStatus
> end; //case of
> CommaDataOutfeed.Clear;
> tmrPollOutData.Enabled := true;
> end;
>
> procedure TfrmMain.ConnectOutFeed;
> begin
> try
> TCP_Outfeed.Connect;
> except
> on E:Exception do
> Begin
> Application.Terminate;
> End;
> end;
> ReadingOutfeedThread := TReadingOutfeedThread.Create(TCP_Outfeed);
> end;
>
> procedure TfrmMain.PollInfeedData;
> Const
> REQUEST = 'GETDATA'+#13#10;
> begin
> TCP_Infeed.IOHandler.WriteLn(REQUEST);
> end;
>
> procedure TfrmMain.tmrPollInfDataTimer(Sender: TObject);
> begin
> tmrPollInfData.Enabled := false;
> PollInfeedData;
> end;
none