Watch, Follow, &
Connect with Us

Welcome, Guest
Guest Settings
Help

Thread: Datasnap timeouts



Permlink Replies: 1 - Last Post: Jun 9, 2017 2:45 AM Last Post By: Registered User Threads: [ Previous | Next ]
Robert Björkman

Posts: 7
Registered: 10/1/11
Datasnap timeouts
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 10, 2017 2:22 AM
Been having some issues with datasnap and timeouts, so I've gone ahead and made some changes...

I had to remove the Terminate/Cancel-events in the TDBXScheduler because it caused strangeness when the socket times out on its own. The socket would be closed from the scheduler thread while it was also closed from the "main" thread causing access violations when using callbacks and such.

It would be great however if someone with a bit of insight into datasnap could comment the changes.

I found the SetTimeout-interface stuff on some german delphi forum, the uncommenting of the timeoutthreads is all my doing though.

Data.DbxSocketChannelNative.pas: implementation uses

uses
  System.TypInfo, Data.DBXClientResStrs, IPPeerClient;


Data.DbxSocketChannelNative.pas: procedure TDBXIdTCPLayer.Open(const DBXProperties: TDBXProperties);

  if Supports(FIdSocket, IIPPeerClientSetTimeout) then
  begin
    (FIdSocket as IIPPeerClientSetTimeout).SetConnectTimeout(ConnectTimeout);
    (FIdSocket as IIPPeerClientSetTimeout).SetReadTimeout(CommunicationTimeout);
  end;
 
  FIdSocket.UseNagle := false;
  .
  .


Data.DbxSocketChannelNative.pas: function TDBXIdTCPLayer.Read(const Buffer: TArray<Byte>; const Offset,
Count: Integer): Integer;

function TDBXIdTCPLayer.Read(const Buffer: TArray<Byte>; const Offset,
  Count: Integer): Integer;
begin
  if Terminated then
    exit(-1);
 
  if FConnected and (CommunicationTimeout > 0) then
  begin
    try
//      TDBXScheduler.Instance.AddEvent(IntPtr(Pointer(Self)), procedure begin
//          Terminate;
//        end, CommunicationTimeout);
      Result := ReadData(Buffer, Offset, Count);
//      if TDBXScheduler.Instance <> nil then
//        TDBXScheduler.Instance.CancelEvent(IntPtr(Pointer(Self)))
    except
      on E: Exception do
          raise TDBXError.Create(SCommunicationTimeout)
    end;
    if Terminated then
      raise TDBXError.Create(SCommunicationTimeout)
  end
  else if not FConnected and (ConnectTimeout > 0) then
  begin
    try
//      TDBXScheduler.Instance.AddEvent(IntPtr(Pointer(Self)), procedure begin
//          if not FConnected then
//            Terminate;
//        end, ConnectTimeout);
      Result := ReadData(Buffer, Offset, Count);
//      if TDBXScheduler.Instance <> nil then
//        TDBXScheduler.Instance.CancelEvent(IntPtr(Pointer(Self)))
    except
      on E: Exception do
          raise TDBXError.Create(SConnectionTimeout)
    end;
    if Terminated then
      raise TDBXError.Create(SConnectionTimeout)
  end
  else
    Result := ReadData(Buffer, Offset, Count);
  FConnected := true;
end;


IPPeerClient.pas

type
  IIPPeerClientSetTimeout = interface
    ['{9924134C-9C7D-464F-8ABE-F3E1E408C566}']
    procedure SetConnectTimeout(const ATimeout: Integer);
    procedure SetReadTimeout(const ATimeout: Integer);
  end;
.
.
TIdTCPClientPeerIP = class(TIdClassIP, IIPTCPClient, IIPObject,
  IIPPeerClientSetTimeout)
.
.
    procedure SetConnectTimeout(const ATimeout: Integer);
    procedure SetReadTimeout(const ATimeout: Integer);
.
.
 
procedure TIdTCPClientPeerIP.SetConnectTimeout(const ATimeout: Integer);
begin
  FTCPClient.SetConnectTimeout(ATimeout);
end;
.
.
 
procedure TIdTCPClientPeerIP.SetReadTimeout(const ATimeout: Integer);
begin
  FTCPClient.SetReadTimeout(ATimeout);
end;
 
 
Registered User

Posts: 33
Registered: 3/4/05
Re: Datasnap timeouts
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 9, 2017 2:45 AM   in response to: Robert Björkman in response to: Robert Björkman
You will also find that there can be infinite waiting with callbacks as well if closing a callback/ shutting down you client - I had to re-write code to get a client to shutdown if a TCP connection was closed prematurely - it would want to re-make a connection to notify its closing a tunnel, but wait forever amoung several other bad "wait forever" scenarios. It seems DS was written for perfect connections, its not robust at all on a real WIFI or other network that could have less than perfection connections.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02