3
votes

I have recently started using DataSnap in Delphi to produce what will be a RESTful web service. After following guides by the man himself Marco Cantu and several others on the internet I have successfully got the whole 'chain' working.

But there is a small issue of speed; the client can now send a stream (along with it's size) to the server (which, because of the bug here DataSnap XE2 and TStream method parameters, is read upto the sent size), and the server will reassemble it into a file and save it on disk.

But foir a 3.66MiB file, this takes over 50 seconds!

Should this be the case? On the server I have:

try
   F := TFileStream.Create('written.dat', fmCreate);
   F.Position := 0;
   F.CopyFrom(Data, DataSize);
finally 
   F.Free; 

And on the client end:

var
  Server: TServerMethods1Client;
  DBStream: TFileStream;
begin
  Server := TServerMethods1Client.Create(SQLConnection1.DBXConnection);
  try
    DBStream := TFileStream.Create('DataSnapServer.exe', fmOpenRead);
    DBStream.Position := 0;
    Showmessage(IntToStr(Server.SendData(DBStream, DBStream.Size)));
  finally
    Server.Free;

Any help appreciated!

Cheers, Adrian

1
"Should this be the case?" No, but it may be a network issue. What happens if you just copy a file that size to the server? What do you see if you ping/tracert the server?GolezTrol
Sounds like an implementation bug: waiting for the timeout to be reached then truncate the returned content. It should handle the Content-Length HTTP header.Arnaud Bouchez
Not the answer, but to say it is feasible: our mORMot RESTFul framework handles custom stream content as expected, just via interface-defined services (no need to go through all the DataSnap plumbings and wizards, and with very good speed) - it can even uses the http.sys kernel-mode server to process the file with no memory copy in the userland memory.Arnaud Bouchez
Since you're writing a .exe file, could it be that a virus scanner is agressively scanning the file while it is written? I think TFileStream automatically buffers reads and writes per 4Kb, which could cause quite a number of re-scans while the file is written.GolezTrol
Turns out that I was writing to a TMemo on the server trace; disabling this really fixes the problem, although I tried the virus scanner one prior - good recommendation! I am guessing the OnTrace is threaded and automatically executes a critical section to make it threadsafe?Adrian

1 Answers

1
votes

On server side, try adjusting BufferKBSize property on TDSHTTPWebDispatcher component. Same property can be found on TsqlConnection component on client.