You are not logged in.
Pages: 1
Yes, it's the same (a little faster but that may be due to differences in hardware, os, .. I guess)
With the suggested way of working (above) it's also way faster.
Thnx again Arnoud
The suggested way of working is much fast, thnx.
Thnx Arnoud!!
Will try your suggestions.
See your mail
Thnx
As you mentioned I did a test bypassing the Http.
The problem - speed issue - still remains.
It is the parsing of JSON that takes so long. Will try on an iOS device next
Did some remote logging
As I expected it is CallGetResult, called from within CallRemoteService (see higher) that's the bottleneck.
This call takes 1 minute 40 seconds on a S3 mini for the aforementioned 580KB (value proven in the remote log).
The actual download is a few seconds.
Did some further detailed testing and (as expected?) it is actually
doc.Init(jsonres);
within CallGetResult that is the cause for the delay.
Any ideas?
Hi Arnoud, been a while
I was under the impression that in
result := CallGetResult(Call,outID);
you convert the content in the body of the http return from the server to a variant.
I stepped through it and it's the above call that lasts longest.
To me it looks like it that the actual download of the content form the server is rather fast.
Size is around 580KB.
Hi
We've a mORMot service running that can return up-to 5.000 records, sometimes even more, in a variant (TDocVariantData).
At the client side we use the generated cross-platform code.
On a desktop, Win32, OSX or iOS Simulator, this client code performs very well. It can retrieve the items on the server almost instantaneous. However running the same client code on a mid-range Android device is slow, up to a minute to retrieve the same amount of data.
Bandwith is a little less on the mobile device (connected to the same Wifi though), but it is not the bottleneck.
The processing of the result on the client is the part that takes longer, 1.5 minutes compared to a few seconds:
In unit mORMotClient we use this to retrieve the data:
fClient.CallRemoteService(self,'GetPatients',1, // raise EServiceException on error
[parJSONFilter],res);
In unit SynCrossPlatformREST:
It is this call in aformentionend CallRemotService,
result := CallGetResult(Call,outID);
that takes way longer.
Any ideas how to speed this up (apart from retrieving less data)?
Is there already something to retrieve a 'paged' result (so in chunks)?
Thnx
Could it be function TSQLHttpServer.RemoveServer never returns true, even when the server was successfully removed from the HTTP server?
XE7 UPD1
Am trying to load some legacy data in batch on server startup with CreateMissingTables().
With a previous version of mORMot this worked without hiccup, now we get a SQL syntax error, a ' , ' in excess.
Am using TSQLRestBatch with AutomaticTransactionPerRow set to a number lower then the number of records to import.
Batch := TSQLRestBatch.Create(self, TSQLContact, 30);
Found two ways to bypass this:
1. Set the AutomaticTransactionPerRow parameter in the TSQLRestBatch constructor to a number higher than the number of legacy records to import. (Not really a solution)
2. Or change in procedure TSQLRestServerDB.InternalBatchStop.
// INSERT Values[] into the DB
SQL := SQL+','+CSVOfValue('('+CSVOfValue('?',fieldCount)+')',rowCount-1);
Statement := nil; // make compiler happy
To
// INSERT Values[] into the DB
if Pred(rowCount) >0 then
SQL := SQL+','+CSVOfValue('('+CSVOfValue('?',fieldCount)+')',rowCount-1);
Statement := nil; // make compiler happy
Or are we overlooking something?
Thnx, first test looks very promising.
We'll keep you posted.
We have a TSQLRestServerDB instance running, exposed via a TSQLHttpServer instance.
On the RESTServer instance there's an interface registered with some functions and procedures. These can be called without any problem from a VCL mORMot client.
Problem though, is the server generated (Mustache) CrossPlatform client wrapper. This code can't be compiled if it's not adapted.
Extract of the code on the server:
TDTOActivePatient = packed record
Id: Integer;
FullName: String;
Gender: TGender;
end;
TDTOActivePatientDynArray = array of TDTOActivePatient;
IPatientAdministration = interface(IInvokable)
['{80091C16-DBA2-494F-A375-28ED102338D9}']
function GetActivePatients: TDTOActivePatientDynArray;
procedure CreatePatient(var thePatient: TSQLPatient);
end;
Extract of the generated client code:
TServicePatientAdministration = class(TServiceClientAbstract,IPatientAdministration)
public
constructor Create(aClient: TSQLRestClientURI); override;
function GetActivePatients(): TDTOActivePatientDynArray;
procedure CreatePatient(var thePatient: TSQLPatient);
end;
/// map "Patient" table
TSQLPatient = class(TSQLRecord)
protected
fFirstName: string;
fFamilyName: string;
fGender: TGender;
fIsActive: boolean;
published
property FirstName: string index 50 read fFirstName write fFirstName;
property FamilyName: string index 50 read fFamilyName write fFamilyName;
property Gender: TGender read fGender write fGender;
property IsActive: boolean read fIsActive write fIsActive;
end;
function TServicePatientAdministration.GetActivePatients(): TDTOActivePatientDynArray;
var res: TVariantDynArray;
begin
fClient.CallRemoteService(self,'GetActivePatients',1, // raise EServiceException on error
[],res);
Result := res[0];
end;
procedure TServicePatientAdministration.CreatePatient(var thePatient: TSQLPatient);
var res: TVariantDynArray;
begin
fClient.CallRemoteService(self,'CreatePatient',1, // raise EServiceException on error
[thePatient],res);
thePatient := res[0];
end;
To be able to compile the generated code we had to make some changes, f.i. define:
TDTOActivePatientDynArray = Variant;
TSQLPatient = class;
The first, TDTOActivePatientDynArray, a return parameter wasn't defined.
The second one, TSQLPatient was defined, but already used/called before it was declared in the unit. Could also have moved the TSQLPatient definition.
With these changes the 'GetActivePatients' function works. The 'CreatePatient' procedure still does not compile (generated code) as the types don't match.
Any ideas how to take it from here? Is there anyone that can point us to a sample in which SOA services are called from a FMX client (CrossPlatform) and that use f.i. a TSQLRecord instance as a parameter?
Thnx
Had the same error.
Does it pass above part of the .inc? Isn't it catched by the NEXTGEN section for iOS...
Pages: 1