#2 Re: mORMot 1 » Infinity and beyond » 2020-11-06 09:43:04


The EWB layout system is an absolute game-changer. Additionally, combined with component creation and interfaces, you have the ability to create truly responsive, modern web apps, that look any way you wish.
You can create components by combining small elements, all in Pascal, no HTML, please see this video:


Regarding mobile apps, qoute from forum: "I also have to do this a lot. In my experience, the EWB Layout functionality is easily good enough for me to actually create a single app that is responsive based on device resolution. You should explore this functionality if you have not done so already, along with the Autosize functionality. The only area where I have had to "tweak" things is the removal of scrollbars on mobile devices."

These days EWB3 will be launched with many more features.

There a trial version and if you say is ok, I can contribute with a licence. I will send a private email.

#3 Re: mORMot 1 » Infinity and beyond » 2020-11-05 17:14:32


My opinion is that Elevate Web Builder is way better than TMS WebCore from a Delphi/FPC developer perspective: EWB has a very nice layout and very nice designed controls (no HTML, no CSS - the RAD way, but you can customize every bit), instead of TMS style where the page is usually designed by a designer and the developer access the controls by ID.

#4 Re: mORMot 1 » mORMot server for Android/IOS » 2020-06-30 08:14:48

Leslie7 wrote:


this is the concept:

1. Compile a  mORMot server with Lazarus into a dynamic library
2. Create an Android  "remote service"/"IOS background app" with Delphi using this dynamic library to start/stop/manage the  mORMot server
3. Access the server from a FMX app via websockets.

Is this a viable path?
Does using websockets use more energy than using intents to communicate?

He asked if is a viable option to connect locally on mobile device to mORMot server? FMX is the client and mORMot Android/iOS background app is the server.
I'm also interested in the same approach, because we can get sqlite encrypted access on mobile, plus MORE IMPORTANT: real unified code between mobile, desktop, server - and only the GUI differs.

#5 Re: mORMot 1 » 10.4 sydney issues » 2020-06-10 04:31:36



Just asking: any performance penalty, or any downsides?

#6 Re: mORMot 1 » Revision 2.x of the framework » 2020-05-13 13:07:51


What @ab said + "with" helps compiler to make some optimization.

#7 Re: mORMot 1 » Fast MM5 » 2020-05-08 20:08:05


I'm not using Linux yet, but THANK YOU! for your hard work and attention to detail.

#8 Re: mORMot 1 » Fast MM5 » 2020-05-06 12:03:25



FastMM4-AVX is any better? Can you make it FPC/Linux compatible?

#9 Re: mORMot 1 » The mORMot on Android » 2020-05-04 17:03:01

ab wrote:

Ah! Make sense now!

mORMot+FPC can act as fast "local server" ("so" library or "dylib") on mobile device. The first use case I wait to test sqlite-access+custom-AES-encryption.
Exchange of data between FMX-project and "local server"  can be made as JSON. Practically you can have on your mobile a replica(subset or integrally) of the main database from cloud-server but sharing the same code (AES, pascal stored procedures, etc)

ab wrote:

I guess we may more easily add Delphi new targets in mORMot2.

Perfect! Because I see a real push from ARM servers.

#10 Re: mORMot 1 » The mORMot on Android » 2020-05-04 12:26:53

ab wrote:

FMX is supported only for the client side (SynCrossPlatform* units), not the server/data side (SynCommons/mORMot/SynSQLite3).
So a FMX project won't be able to use the mORMot SQlite3 features.

Whereas with FPC, it will work, as the Alfred sample shows.

That's what I wanted to say: mORMot+FPC packed in shared library. This library can be used by a FMX project.

#11 Re: mORMot 1 » The mORMot on Android » 2020-05-03 19:00:42

AOG wrote:

This is a pure Pascal native Android app.

Can I use sqlite-db-acces from mORMot as Android-library(.so, .a) or iOS .dylib linked to FMX project?
For example a subset of main database will be downloaded from server to local device to speed up things, so the most used tabled are in place and acts as a cache.
I can use the same code(partially) on the main server and also on the local device - FMX (views) and shared library (data access and logic).

#12 Re: mORMot 1 » Fast MM5 » 2020-04-30 20:50:13

ab wrote:

I could help Eric make it FPC/Linux compatible for sure, but its use as pure GPL may be not worth it for some mORMot users.

Some benchmarks will tell the answer, especially in heavy multi threaded scenario.
If the improvement is real, I don't think commercial users will not spend equivalent of 16GB DDR4.

Anyway FPC/Linux needs a good MM, so this is a nice opportunity to investigate - when a quality product is offered at a decent price, people will pull the trigger.

Also , please read: fastmm5-now-released-by-pierre-le-riche-small-background-story/

#13 Re: mORMot 1 » mORMot - Windows (http.sys/FastMM4) vs Linux » 2020-03-29 14:20:38


1. Please include all this info in a blog post or in manual.

2. Brilliant idea, especially for the websockets:

ab wrote:

I would like to rewrite our HTTP server in the close future, to allow HTTP/1.1 and even more websockets connections be fully thread-pooled.

- can be thousands of websockets JS clients who waits for notification;
- or another scenario for multi tenancy database, every office server(can be thousands, every tenant with his office-server) must be connected 24/7 to web-relay-server waiting for notification of incoming call

#14 Re: mORMot 1 » mORMot - Windows (http.sys/FastMM4) vs Linux » 2020-03-29 11:24:30


Thank you very much. I'll investigate when I have some time.

What aboutL

emk wrote:

- threading: "http.sys" spawns some fixed worker threads who process many connections, what about Linux, every connection has it's own thread?

#15 mORMot 1 » mORMot - Windows (http.sys/FastMM4) vs Linux » 2020-03-28 21:07:34

Replies: 6

Reading topic Thanks to all for mORMot/Zeos + Linux!!! makes me wonder what are speed/advantages differences between Windows(Delphi) and Linux(FPC).
Many people are not familiar with Linux(including me) and I think this topic can shed some light. Besides Windows requiring a license:

- speed differences: Windows has a very fast "http.sys" and "FastMM4" memory manager, Linux? (I know FPC has some slower MM)
- general speed differences;
- threading: "http.sys" spawns some fixed worker threads who process many connections, what about Linux, every connection has it's own thread?
- websockets: the same question
- proxy: can be put directly on web or needs a proxy? (I'm asking for both OS-es. Any penalty?)
- any other difference worth mentioning.

Thank you.

#16 Re: mORMot 1 » Relay server scenario » 2020-01-16 18:18:22


What @sakura is asking is the same methodology implemented by TeamViewer, GoToMyPC, etc:

The client is trying to connect directly to server but if it fails, will try by connecting to a Relay-server (which is maintained by TeamViewer company) to which, the desired server is already connected as a client. So relay server acts as a forwarder between the client and the server(which is connected as a client to relay server) without making any hardware changes.
This is the most useful setup when direct connection fails and that's why software like TeamViewer works every time no matter how complicated infrastructure exists or how many firewalls are between the peers.

In my opinion is better to use a full TCP/IP connection between Office-server and Relay-server(use Indy maybe), but only when is needed because on the Relay-server side it uses one thread per connection.

I would go with this scenario:
1. Office-server is connected to Relay server by Websocket protocol (only for notification of first request of a session).
2. Client sends request to Relay.
3. On first request, Relay sends notification by websocket to Office-server and waits for full-TCP/IP-connection initiated by Office-server.
4. Office-server opens full-TCP/IP-connection to Relay.
5. Relay picks-up the full TCP/IP connection and sends the client request to Office-server, waits for processing, gets the response and send back to client, release the full-TCP/IP-connection handle without closing.
6. If there is no traffic on TCP/IP full connection for let's say 15 min, Relay closes TCP/IP full connection.
On subsequent requests only steps 2. and 5. would happen.

Or, another possibility is to use message-brokers like RabbitMQ, where Client and Office-server are connected as clients to RabbitMQ-server(Relay).

#18 Re: mORMot 1 » Delphi 64bit sqlite compilation » 2019-09-20 20:07:45



mORMot is a open-source project, so you can use C++ Builder Community Edition.

#19 Re: mORMot 1 » THttpApiWebSocketServer Features Requests » 2019-03-03 13:29:48

mpv wrote:

we switch to RabbitMQ with websocket plugin for our notifications task

Which websocket plugin? (Web-stomp?) It's reliable? Any experience to share?

#20 Re: mORMot 1 » THttpApiWebSocketServer Features Requests » 2019-03-02 21:09:04


@pvn0 search for "delphi amqp".
Kbmmw also has an Amqp 0.91 library.

#21 Re: mORMot 1 » 64 bit support for Delphi » 2019-01-30 16:40:19


Please don't be upset but sounds rude to me also.

Please grant @Greg0r wish and make us all happy. smile
Thank you.

#22 Re: mORMot 1 » mORMot in Windows Subsystem for Linux » 2019-01-09 11:11:37


I also confirm VirtualBox is very easy to setup and it's free.

#24 Re: mORMot 1 » Embed SQLite C object files into application » 2019-01-03 21:07:00


I see now that FastMM4-AVX is compatible with FPC-64bit:

Didn't compile under 64-bit version of FreePascal

Can you test if the problem described here is still reproducible with latest FastMM4-AVX?
If is still reproducible, I can contact Maxim Masiutin (author of FastMM4-AVX) to look over it.

#25 Re: mORMot 1 » Embed SQLite C object files into application » 2019-01-03 12:24:23

greedy wrote:

FPC is open-source, you can add all of them to it.

I'm not assembler guy neither CPU-extensions guy (ex SSE). This is the remarkable work of @ab.

greedy wrote:

as written above, I'm not sure why it should not work with FPC x64. I'm using it on FPC x64 for linux...
Btw there is also a newer version which might benefit from modern cpus: https://github.com/pleriche/FastMM4/pull/38

I know about FastMM4-AVX. In description says: "support for Lazarus 1.6.4 with FreePascal (the original FastMM4 4.992 requires modifications, it doesn't work under Lazarus 1.6.4 with FreePascal out-of-the-box, also tested under Lazarus 1.8.2 / FPC 3.0.4 with Win32 target;"

I think FastMM4-AVX supports only FPC-Win32.

#26 Re: mORMot 1 » Embed SQLite C object files into application » 2019-01-02 22:51:23


Thank you for your response.

Maybe I'm misjudging but regarding mORMot on Windows, seems old good Delphi+Win32 has the most optimizations:
Delphi+Win64 doesn't have Sqlite AES encryption and most of the routines are PUREPASCAL.
FPC+Win64 doesn't have FastMM4..

I would like to use Win64 because my design involves multi-tentant databases, but also encryption is very important. So, I have to choose between 2 strategies:
1. Use FPC+Win64, but I'm a little concerned about speed, about not having FastMM4 and other novelties..
2. Use Delphi+Win32 and every Sqlite database will have smaller cache than default (reside more on OS cache), every sqlite database connection will expire&close when it's not used more than 15min and eventually, if is needed, running many mormot servers on the same machine but different ports and to allocate fewer threads to every mormot server.

I'm glad to here pro and cons for every way. Thank you.

#27 Re: mORMot 1 » Embed SQLite C object files into application » 2018-12-31 10:57:22


ab, Thank you for your great work! and definitely to maintain so many compatibilities is a titanic task.

It seems that FPC+Win64 is the way to go if I want to use AES Sqlite encryption and also USEZLIBSSE.

I never used FPC, so regarding mORMot:
FPC+Win64 has any drawbacks against Delphi-Win32, or Delphi-Win64?
I know that Delphi-Win32 has a lot of assembler optimizations, it's still the case with FPC-Win64?
FastMM4 will "feel" the same under FPC+Win64?
FPC+Win64 will be the "same" with Delphi-Win64 in regard to fast http.sys?

Thank you.

#28 Re: mORMot 1 » Embed SQLite C object files into application » 2018-12-30 13:23:59


Any news on AES Sqlite encryption on Delphi-Win64?

And as a curiosity why Delphi-Win64 was not supported from the beginning?

#29 Re: mORMot 1 » mORMot and Elevate Web Builder » 2018-11-20 15:11:45


I don't think mustache templates are needed, just only some dedicated methods to provide the need JSON in a special format:

a) if you use EWB datasets, this is the link for the needed JSON: EWB JSON reference
b) if you use objects, EWB will know to deserialise your object and automatically create subobjects if the main object descends from TPersitent.

When the time comes I hope I can contribute with some code.

#30 Re: mORMot 1 » Benchmark information » 2018-04-09 14:52:50


First of all thank you for all responses.

I don't "feel" the need for DTOs, because I'm "cheating" - I'm Load-ing aggregates from local replica, so performance is very good.
As @ab says I'm certain that any abstraction will pay dividends sooner or later, I'm not just there to collect them smile

In the middle future when I'll arrive to my need of deserialize TObjectsLists, I'll try my best as I propose and make a pull request and maybe @ab will polish it. Maybe I'll even try to make a option j2oUseCocForArrayNames (Convention over Configuration) - ex: if json array name is "OrderDetails", I'll look for a class name 'T' + 'OrderDetails' + 'Class'.. I have to think...

#31 Re: mORMot 1 » Benchmark information » 2018-04-07 16:02:39


I'm doing what you say:

I have "onion" type layering - GUI layer uses "Controller" layer, which uses Domain layer. Domain doesn't know about "Controller", "Controller" doesn't know about GUI. In Domain layer I have defined PODO objects with business logic. Domain layer has persistence ignorance - I have some services implemented (every call is a Unit-of-Work) who Save the aggregate remotely or Load the aggregate from local replica. Domain objects are serialized directly by these services. I have to think, but for the moment I don't see how I'll benefit from DO->DTO->json instead of DO->json. I read the arguments but somehow doesn't apply to me..will see.

For me is important that DO has the same definition on client, server and EWB client so I can re-use the same business logic and validation rules(that's why I need TObjectList).
So I have common ground, Domain Objects:
- inherits from TSynPersistent on server,
- inherits from my TEntity on delphi-client (also every object/ObjectList has attached a in-sync memory TDataset - TFDMemTable, for easy dual-binding db gui widgets),
- inherits from TPersistent on EWB-client(also every object/ObjectList has attached a in-sync memory TDataset(EWB-type) for easy dual-binding db gui widgets),

Services for persisting differs for all 3, but Domain Objects are the same (PODO with business logic and validation).

I'm just presenting my case that I'm not hardcore db-programmer.. Not anymore.. smile

... but still, my PODO objects are generated with a code-generator(which I written) from db-schema. The idea is when I change db-schema, I run code generator (to generate classes with Set&Get), so I have a single entry of changes. Those generated "simple bags of getter&setters" are my DTOs from which I inherit and adding business rules&validation and they become my Domain Objects.

#32 Re: mORMot 1 » Benchmark information » 2018-04-05 20:28:14


So you say you have 2 types of objects for one entity: DTO(record&arrays) and Domain Objects(TSQLRecord with logic?)?
You have something like this: DO <-> DTO <-json-> DTO <-> DO <-> DB?

Please shed some light. Thank you.

EDIT: I read Index» mORMot Framework» Difference between DTO and entity
From that thread, this corresponds to my needs:   smile

I know people must use DDD/DTO for a reason, but so far I feel it's a little over-abstraction for my own purpose, I might be wrong

#34 Re: mORMot 1 » Benchmark information » 2018-04-05 09:01:36


and that instantiation (at least with FastMM4 + TSynPersistent) is almost never the bottleneck.

I thought that is not worth it, because if it was, was already implemented smile

TObjectList is not easily unserializable in the SOA or the ORM, since we need to specify each class of the items.

I need TObjectList because I want to have common code (at least DTO and validation) between Delphi-client/mormot-server/future-EWB-client (doesn't have T*ObjArray). Also I see a lot of people in forum try/need to use TObjectList, so I propose a solution:

RegisterClass('OrderDetails', TOrderDetailsItemClass);
RegisterClass('OrderPayments', TOrderPaymentsItemClass);

in function JSON2Object, make a new option: j2oGetItemClassFromArrayName

{"Order" = {"Client" = "XYZ",
           "Date" = "2012-04-30T02:15:12.356Z",
           "Amount" = 1000,
           "OrderDetails" = [
                            {"itemName" = "Clock",  "qty" = 1, "Value" = 100},
                            {"itemName" = "AClock", "qty" = 1, "Value" = 900}
           "OrderPayments" = [
                             {"type" = "cash", "value" = 600, Date = "2012-04-30T02:15:12.356Z"}
                             {"type" = "card", "value" = 400, Date = "2012-04-30T02:15:12.356Z"}

With this solution can use many sub-TObjectLists and will solve the problems for a lot of people.

#35 Re: mORMot 1 » Benchmark information » 2018-04-03 20:28:13


3. Sorry, my mistake, I didn't explain it correctly: please re-read point 3. but with the addendum that I was talking about deserialize object lists (You know when a "Order" contains a TObjectList with "OrderLines").
In this procedure:

procedure TJSONToObject.HandleObjectList(Lst: TObjectList);

you have somewhere in the middle:

Item := ItemInstance.CreateNew;

With your vast experience, do you think it's worth it to have pool of objects for every type of TObjectList I use (ex: "OrderLines" - pool of 10 records/thread). So when the line ItemInstance.CreateNew is executed will retrieve from pool if objects are available, otherwise create one?

Note: For me this deserialization happens on the server, because clients sends a Json object, I deserialize, run some validations and after than write it to db.

#36 Re: mORMot 1 » Benchmark information » 2018-04-03 14:00:15


1. Forget my ignorance/lack of knowledge, but from your blog posts, I found out that avoiding LOCK instruction is crucial for good performing multi threading apps, because it will flush cache cores; that's why mORMot avoids allocating memory, char conversion, etc.. I read that atomic InterlockedXXX is cheap, but every InterlockedXXX will not generate a LOCK instruction? so it's no better to get rid of them where is not needed?

2. Since you compiled with SQLITE_THREADSAFE=1, can I change the settings to SQLITE_CONFIG_SINGLETHREAD from your code?

3. I see that every time you deserialize a JSON array, every object in the list is created. It's not worth it to have a fixed small pool of that kind of object? Let's say I can have a fixed small pool of "OrderLines" of 10 objects. Most of Orders will have maximum 10 OrderLines, otherwise if it has ex 12, 10 will be taken from pool, 2 created. I say "fixed", so the array to be maximum fast and not thinking to supplementary allocations/deallocations. A configuration setting with PoolCapacity can be created for every registered class. What do you think? Or creating an object is so fast that it doesn't worth a pool?
EDIT: Configurable fixed pool per class per thread (no synchronization between threads, no allocation for supplementary objects).

I know that what I'm asking here is premature optimization, but it's good to know and few optimizations here and there makes a better performer.

#37 Re: mORMot 1 » Benchmark information » 2018-04-03 08:38:54


Thank you for taking time for such long response.

I lived with the impression that "smOff" is a very dangerous state, but since it's application-crash free and since hardware-crash can be prevented, and the most important, after a crash usually deleting the journal, puts me back in business, sounds very good.
I think for master server where I have control is good to have "off exc" and for client replicas it's better "normal exc", because on client I don't know if they have UPS or something like this.

Anyway, what I'm doing is work in progress and is not in production and sync between master and slave will be made with a message broker, but I 'll come back with results and more testing is done.

Since I'll have one database connection per database always (multi-tenant) and I'll control with a critical section which thread gets the connection, compiling with SQLITE_THREADSAFE=0 should help(avoiding the mutex)? Do you have any benchmarks here? smile

#38 Re: mORMot 1 » Benchmark information » 2018-03-30 23:03:28


Sorry for bothering, but in your production server/s do you use "off exc"?
Thank you.

#39 Re: mORMot 1 » Benchmark information » 2018-03-30 16:44:04


Any chance for this scenario to happen?

Post some inserts in transaction "n" to master-server ("off exc" - maybe transaction "n" is in journal, but not in db), replica-client gets a message to get updates, retrieves immediately updates from transaction "n" (maybe gets those updates from page cache), master server crashes (and I delete journal manually) and in the end master-server will have "n-1" committed to db and replica will have "n" committed to db.

In other words the question is: in "off exc" mode, by any chance, any update can be read by subsequent select before is synced to disk?

EDIT: Replica-db can check, when takes updates, if his "transaction-id on replica" <= "n" "transaction on master", otherwise means a problem happen and needs manual intervention.
But anyway if somebody knows the answer for previous question is good to know.

#40 Re: mORMot 1 » Benchmark information » 2018-03-30 07:54:18


Use Sqlite3 in "SQLite3 (file off exc)"

I never used Sqlite., so I ask: If somehow I have to force turn off exe-server with multiple Sqlite opened connections in "off exc" is not a big chance of corruption?

#41 Re: mORMot 1 » Benchmark information » 2018-03-29 18:03:28


There are TWO Sqlite3 engines involved here.
And since smFull involved only virtual tables, not real tables, this setting doesn't have any impact on performance in this particular benchmark.

I undestand now.

2. Since DB is the most expensive operation on server, in your opinion, is worth switching from faster inserts Firebird embedded to slower inserts Sqlite? ("Trans" 4987(Zeos Firebird) vs 1643(full exc)).
Note1: I started to look at Sqlite since you made AES encryption for SQLite smile That's why, I started to benchmark, but I'm somehow upset that is slower than Firebird especially in the area that I have the most interest - inserts.
Note2: I didn't have any corrupted database with Firebird.

#42 Re: mORMot 1 » Benchmark information » 2018-03-29 13:47:36


Yes, it was in a VM but these results are on metal (only 10 records - for me this is a realistic scenario):

Insertion speed
 	               Direct	Batch	Trans	Batch Trans
SQLite3 (file full)	128	1314	1150	1307
SQLite3 (file full exc)	204	1768	1643	1680
SQLite3 (file norm exc)	251	2079	1961	1831
SQLite3 (file off)	240	2711	2650	2796
SQLite3 (file off exc)	13531	20120	18691	19305
ZEOS SQlite3	        94	749	743	684
FireDAC SQlite3	        7057	9407	11428	12437
ZEOS Firebird	        1256	4290	4987	4286
FireDAC Firebird	3865	12004	9478	12484

they just changed the default settings for better performance.

Even that they've changed initial settings, I see that you test "Firedac Sqlite" with "smFull"

    {$ifdef USEFIREDAC}
    Test(TSQLDBFireDACConnectionProperties,FIREDAC_PROVIDER[dSQLite],'','','',' SQlite3',true,smFull);

So, "Firedac Sqlite" is "smFull, exclusive" and has 11428 inserts/s(Trans), where your "SQLite3 (file full exc)" has 1643 inserts/s(Trans). So maybe they have bigger buffers or some sort of setting which increases inserts 8x.

When reading one row (which is a very common use case for an ORM), FireDac is more than 10 times slower than our native version...

I don't argue that reading speed is very good but for me writing speed is essential because almost all readings happen on client from slave replica.

I doubt we have anything to learn from the Delphi RTL and its DB.pas design...

Thank you for your great work, I'm trying to be constructive and maybe some time to time we find something you miss smile

I'm interested only on "smFull".

#43 Re: mORMot 1 » Benchmark information » 2018-03-29 09:39:16


I read those pages from SAD, but how to explain "Firedac Sqlite" better performance since is also tested with "smFull":

    {$ifdef USEFIREDAC}
    Test(TSQLDBFireDACConnectionProperties,FIREDAC_PROVIDER[dSQLite],'','','',' SQlite3',true,smFull);

Results: (also, same 10 records)

FireDAC SQlite3    6644    2913    5117    5980

What is the "magic" behind Firedac Sqlite provider? Direct 15x, Trans 2x? I think this magic worth investigated and imported into mORMot smile

#44 Re: mORMot 1 » Benchmark information » 2018-03-28 21:29:14


I wanted to evaluate Sqlite vs Firebird embedded.

In example 15, I switched to 10 records because is a realistic scenario (inserting an "order" object it has usually 7-10 record).

Insertion speed:

                             Direct    Batch       Trans        Batch Trans
SQLite3 (file full)        424    3518        2673        1756
SQLite3 (file full exc)  178    3324        2130        3278
ZEOS Firebird             924    2092       2942        2464
FireDAC Firebird        3795  11507       9182       11834

Why "FireDAC Firebird" is 3 times faster than "Zeos Firebird" and also 3 times faster than "SQLite full exclusive", since Sqlite access is maximum optimized in your framework? and I mean for "Trans" because I don't think I'll use "Batch" (anyway Firedac has also a very optimized batch).

Note: I need maximum safety, and since Firebird is implicit in "Full" mode is fair that Sqlite to be also in "Full" mode.

Thank you.

#45 Re: mORMot 1 » mORMot Delphi REST Server without ORM » 2018-02-16 11:07:14


Indeed, FireDAC is really powerful an I use it extensively on client app(memory tables, cloning, ...), but on server side, where scaling is critical, using FireDAC as TDataset as most people will think to do it, has some drawbacks: TDataset if it's not unidirectional will fetch all rows in memory (which will allocate memory, which will LOCK any other CPU cores from processing,..), will fire all/any events related to TDataset and then make not so optimized conversion to Json. Instead,  ISQLDBRows will fetch only one record at time and convert it to Json row directly from ISQLDBRows row-buffer.

I didn't use FireDAC Phys. Seems to me, to be one layer below TDataset (with speed advantages), but still doesn't have direct conversion to Json from ISQLDBRows row-buffer.

The both scenario will work, but ISQLDbRows is more optimized for server side and FireDAC is best at client side.

#46 Re: mORMot 1 » mORMot Delphi REST Server without ORM » 2018-02-13 08:53:51


You don't need to use TFDQuery. Using TFDquery will be fine but in the end it's somehow the same approach as Datasnap (many allocations in memory -> many LOCK instructions -> slower performance). Use synDBZeos unit to access Firebird and there you have ISQLDBRows.FetchAllToJson. It is the fastest mode to return database rows to corresponding Json.

Use method based service: http://blog.synopse.info/post/2010/07/1 … phi-7-2010

#47 Re: mORMot 1 » a offtopic question » 2017-09-09 17:33:34


Yes, in a method, all local variables are independent from other threads.
Simple types, integer, boolean, etc are allocated directly on stack. A string is allocated dynamically on heap (which is global space, because a string in Delphi can be like 2GB) and also on current private stack is allocated a pointer to that global space, so only the current thread "knows" the location of that string allocated on global memory. So it's thread safe.

But what I tried to explain in previous post is every time you modify a string, an allocation on heap is made(almost every time), what means other CPU cores are blocked, so that current CPU core can claim a memory space for that string. That induces a lot of LOCKs which degrades performance. That's why mORMot is so fast because is  trying to prevent those dynamic allocations . If your server app is not very intensive or serves only dozens of users, ignore my comment about performance.

Global variables must be protected.

#48 Re: mORMot 1 » a offtopic question » 2017-09-09 13:59:43


1. Every thread has it's own stack (usually 1 MB, but can be changed). Every variable(of a method) of basic types/records/static arrays is allocated on stack (it's private space of that thread).

2. You can't make a read-modify-write of global variable without CriticalSection because it not atomic operation (is 3 operations) and a thread switch can happen exactly between those 3 ops. So you can't make index := Inc(index) without CS.

3. Let's say you only want to write to an integer(32 bit) in multiple threads without protecting with a CS. It is an atomic operation as long as memory manager align memory addresses to at least 32bit. If you write an Int64 from multiple threads and memory is aligned 32bit you can have bad results (it's not atomic).

4. If you decide to use point 3. (write integer, with memory aligned 32 bit, without CS) you must know that operations executed are not in the order you elaborated in your program, but are executed in a different order because of optimizations in L1 cpu cache. If you need exact order you must protect with a memory barrier. CriticalSection, SRW, InterlockedIncrement, etc .. they all have memory barrier.

5. Programming without LOCK is an super-expert task. Optimize your algorithm so you minimize the number of LOCK (don't allocate strings - work with a buffer, reuse the same instance many times, etc). And when you have to LOCK use InterlockedIncrement, InterlockedExchange, etc... They are the slimmest type of LOCK (on modern cpu is one instruction). If you need more, use CriticalSection or SWR (Vista+)..they are also implemented with InterlockedIncrement, but if the LOCK is taken by another thread they degrade successfully to kernel WaitForSingleObject. You can use InitializeCriticalSectionAndSpinCount so the CS makes like 4000(as many as you want) round-trip instruction trying to acquire the lock, before degrades to much heavier WaitForSingleObject which makes the same thing. For small and fast locks this spin count try is a huge improvement.

#49 Re: mORMot 1 » Unserialize JSON with complex TObjectList structure » 2017-09-07 11:54:23



I have hard time also to deserialize into TObjectList. For me, I can't use TCollectionItem or array.
There is a possibility to register the class so the deserialize have enough info to produce TObjectList of T, or TObjectList<T>  even it's only for Windows?
Or can you implement something like this? Even if will not support old versions of Delphi or FPC. I think will be high use for many people with specific case and I think in time FPC will catch up with generics.
Or can be simple TObjectList and the user provide the class as parameter or something like this.

Thank you.

#50 Re: mORMot 1 » any necessary to implement Snowflake-IdWorker for global unique ID ? » 2017-09-06 14:10:40

ab wrote:

The algorithm used ensure that.
If each TSynUniqueIdentifierGenerator has a single ProcessID value (set e.g. in the settings file of the node), then you can be sure that there won't be any collision.
Another benefit is that it is time-based, so it will be globally increasing (which eases a lot indexation and balancing), and you can retrieve the creation timestamp from the ID (no need to have the time stored in another field).

I thought that ProcessID = Windows ProcessID or something like this. I get it now, but needs that every node to be registered and get a unique ProcessID before can post to server. It not a big deal. Also it must keep track of many instances of the client to have different ProcessID.
But I think it's not safe enough.. I saw many times (for different reasons) that client time is set back manually for let's say 2 hours, so with a "little luck" the same time can occur again in the same ProcessID.

Board footer

Powered by FluxBB