Newsgroups : Borland : borland.public.delphi.internet.winsock : 2008 Feb : Re: Lag in data reurns using TCP_Infeed

www.cryer.info
Managed Newsgroup Archive

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;

Replies:

none

In response to:

www.cryer.info
Managed Newsgroup Archive