#51 Re: mORMot 1 » Documentation updated to revision 1.15 » 2014-11-03 08:45:30

Any chance of a web-based, google-searchable HTML documentation?

PDF for technical docs is quite on the impractical side, especially with so many pages, and it's a bit sad to have all that information stay basically unreachable for everyday use. smile

#52 Re: mORMot 1 » WinHTTP, http.sys and WebSockets » 2014-08-19 15:36:46

ab wrote:

But the providers (especially on iOS) add some serious limitation (like 256 bytes maximum length) or security requirements (like explicit SLL certificates).

Yes, they should really only be used to pass commands, rather than data.
For instance for a mail app, you wouldn't pass the new mails, but a command like "check new mails", and the app would then fetch the mails through regular means.

I guess it helps to consider platform notifications as being barely improved remote keypress events smile

But mostly the whole point is that on mobile devices, either the application is active and it's okay to poll like a madman, or it's not active, and you can use neither websockets nor long polling. Desktops and laptops are a different story of course.

Another advantage of polling when the app is active is that you can report connection lag to the user, which is quite important for a chat app, multi-player game or trading views!
With long poll or websockets, you can't tell connection lag apart from a lack of updates... unless you "ping" frequently, but then you're no better than polling.

#53 Re: mORMot 1 » WinHTTP, http.sys and WebSockets » 2014-08-19 13:08:31

As a conclusion, I would recommend the following, for any project:

Use WebSocket for client notifications only (with a fallback mechanism to long-polling - there are plenty of libraries around);
Use RESTful / JSON for all other data, using a CDN or proxies for cache, to make it scale.

Cloudflare recently began adding websocket support
http://blog.cloudflare.com/cloudflare-n … websockets
though obviously there is no caching smile

I'm not sure long-polling is a very good alternative to websockets: it will still incur the same scaling issues as websockets (since it has to bypass the CDN), it has associated risks of timeout throughout the wire (can miss some notifications, especially on mobile connections, and you don't have receipts).
The security advantage is over WSS is marginal at best: websockets data goes in well delimited messages that are just as inspectable (or not) as the random binary or malformed data you can pass over http.

That said, for instant notifications the best solution are probably the platform's push notifications, which are centralized on a single service and can thus happen even when an application is not active. Long polling and websockets both require the application to be active.

However for data not specific to a client, such as chat, news, trading data, etc. in my experience good old brute-force high-frequency polling can work very well. It's *very* CDN friendly, if you set 1 second caching f.i., you can serve a million of clients with 1 refresh per second while the main server will get just dozens of requests per second, which is easily manageable.

#54 Re: mORMot 1 » hello world mustache » 2014-05-12 15:18:01

ab wrote:

@Eric & @Chapa
Logic-less templates have other advantages, like 100% uncoupling logic and presentation (whereas PHP, Razor or DWS do not).

They allow coupling, but don't dictate it. DWS has server-side compilation and strong-typing, so it's not like PHP where you can never now exactly what access what and how or when.

A downside of logic-less data-driven templates is that they're runtime-evaluated, with no strong typing, so they require more effort to maintain to maintain, and are error-prone (a weakness shared by untyped languages like PHP).

ab wrote:

AJAX requests represent only a small portion of web pages - and Mustache was designed for real web site (used by Twitter or by Google, in its parent ctemplate).

I disagree, the XML portion of AJAX is pretty much dead, but the asynchronous, javascript-driven aspects have become ubiquitous.

Pretty much all of google and twitter webpages are JavaScript applications, which load not just the data asynchronously, but the presentation and the code itself, and arguably google "webpages" are architectured like traditional fat clients, with dynamic libraries, data access drivers, UI drivers & APIs, etc. they just happen to run in a web browser.

If you look at trends for gmail, charts, maps, google+, analytics, adsense, drive etc. they're all ever more heavy on the client-side logic, and they're all relying on javascript-driven asynchronous loading (many even have loading progress bar or pacifiers, which I don't consider a progress btw)

While mustache and logic-less templates was interesting as a reaction to PHP (and JSP), I'm not convinced it still is very relevant: you can built simple stuff easily with mustache, but you can't build modern web UIs with it, not without throwing a lot of JS or going through extra hoops. Popular template engines these days seem to all have logic.

#55 Re: mORMot 1 » hello world mustache » 2014-05-09 06:52:09

Very nice results!

However, I heartily disagree on you benchmarking conclusions for several reasons wink

Perhaps it's my scientific training, but I believe that focused experiments & measurements always yield interesting fundamental insight.
And case in point, your benchmark is synthetic and focused, where Mandelbrot measures tight loops and simple floating point operators, your benchmarks measure loops, buffer writes and string lookups.

Also, Mustache js isn't really optimized for speed, but for size (hence all the Regular Expressions), and there are faster, Mustache-compatible JS libraries (like Handlebars f.i, which is said to be 2x faster than Mustache, but that in special cases can be 100 times faster).
The reason why optimizing for size makes sense, is that in a "real world" high-performance application, you shouldn't be processing the templates on the server-side in the first-place, that's why I think your benchmark is no more "real-world" than Mandelbrot. Though it likely provides more insight on your coding skills than on the Delphi compiler's own strength I'm afraid

Logic-less templates real strength comes in client-side processing, where they have numerous advantages:
- processing power linearly goes up with the number of clients, and thus is never an issue as long as it's fast enough for the slowest client
- server-side CPU requirements are limited to data-extraction & JSON generation
- templates are static, and thus can be cached on the client (zero bandwidth after 1st load) or served by geo-located CDN (practically unlimited bandwidth)
- server bandwidth requirements are reduced to just serving the data
- since the templates are logic-less, you don't leak any business know-how to client-side execution
- fundamentally different rendering of the same data from the same server is possible, without touching anything on the server, and with no risk of a faulty template/rendering affecting server performance

So where a server-side Mustache will result in ever-increasing load, especially bandwidth load which you're likely to run out well before you run out of CPU on a web-based application, especially if want to serve the whole world, a client-side Mustache will only be limited by the data extraction & bandwidth rates, ie. the speed at which you can extract, generate & send the data.

And when the data itself can be cached & shared (even for short durations), there is practically no limit to scale-ability.

Case in point, my current DWS WebServer experimentation involves serving datasets up to the megabyte range, with usage spikes of hundreds of simultaneous clients, the megabyte of data getting rendered to several megabytes of HTML (once you factor scaffolding & class tags for convenient CSS presentation + IDs for JS interactivity, html quickly balloons up). All this from a mere 10Mbit/s server, which if you do the maths, just wouldn't have the bandwidth (nor the latency, nor the CPU) to handle the load on its own.
The client-side tech is not Mustache, but the fundamentals of client-side rendering & geo-located caching are the same (in my case, it's Cloudflare that's takes the brunt of the load). During a time one link got popular, it averaged a week at 30000 pageviews per day, that's plenty of gigabytes of data, and even more gigabytes of rendered html if it had been done server-side, and way more than the server could have handled on its own.

#57 mORMot 1 » SQLite open_v2 » 2013-12-30 15:41:26

Eric
Replies: 2

Currently TSQLDataBase.DBOpen uses sqlite3.open, it could be nice to use open_v2 instead and the extra flags it supports.

Basically 'open' should be replaced by 'open_v2', an extra parameter with the flags added (default value SQLITE_OPEN_READWRITE or SQLITE_OPEN_CREATE), and the following constants added:

  SQLITE_OPEN_READONLY       = $00000001;  // Ok for sqlite3_open_v2()
  SQLITE_OPEN_READWRITE      = $00000002;  // Ok for sqlite3_open_v2()
  SQLITE_OPEN_CREATE         = $00000004;  // Ok for sqlite3_open_v2()
  SQLITE_OPEN_DELETEONCLOSE  = $00000008;  // VFS only
  SQLITE_OPEN_EXCLUSIVE      = $00000010;  // VFS only
  SQLITE_OPEN_AUTOPROXY      = $00000020;  // VFS only
  SQLITE_OPEN_URI            = $00000040;  // Ok for sqlite3_open_v2()
  SQLITE_OPEN_MEMORY         = $00000080;  // Ok for sqlite3_open_v2()
  SQLITE_OPEN_MAIN_DB        = $00000100;  // VFS only
  SQLITE_OPEN_TEMP_DB        = $00000200;  // VFS only
  SQLITE_OPEN_TRANSIENT_DB   = $00000400;  // VFS only
  SQLITE_OPEN_MAIN_JOURNAL   = $00000800;  // VFS only
  SQLITE_OPEN_TEMP_JOURNAL   = $00001000;  // VFS only
  SQLITE_OPEN_SUBJOURNAL     = $00002000;  // VFS only
  SQLITE_OPEN_MASTER_JOURNAL = $00004000;  // VFS only
  SQLITE_OPEN_NOMUTEX        = $00008000;  // Ok for sqlite3_open_v2()
  SQLITE_OPEN_FULLMUTEX      = $00010000;  // Ok for sqlite3_open_v2()
  SQLITE_OPEN_SHAREDCACHE    = $00020000;  // Ok for sqlite3_open_v2()
  SQLITE_OPEN_PRIVATECACHE   = $00040000;  // Ok for sqlite3_open_v2()
  SQLITE_OPEN_WAL            = $00080000;  // VFS only

#59 mORMot 1 » SynZip Check method shows error dialogs » 2013-12-18 13:58:48

Eric
Replies: 2

In case of errors, SynZip has a Check function, which displays errors with

   

MessageError(IntToStr(aCode),'SynZip');

However that can be called from the HTTP worker threads (among others), which may be running in a service, so there may be no one to see the error. It should probably be something like

 

raise Exception.CreateFmt('SynZip %d', [aCode]);

So that an exception is appropriately triggered, and the code calling SynZip can react appropriately.

Even for interactive debugging it can get problematic if you have a few hundred of such errors fired from a tight loop, it'll overwhelm your screen with as many error dialogs, which just can make Windows crawl before you get a chance to terminate the app (happened to me)

#60 Re: Fast JPEG decoder » Fast JPEG encoder » 2013-12-02 09:52:23

Thanks! A bit out of budget as it's for experimenting (don't know if you caught my Mandel experiment why it was online).
GPU is fast, but servers with GPU are very expensive.

Currently my best solution is libjpeg-turbo (http://libjpeg-turbo.virtualgl.org/) using the headers from http://www.opengl24.de/header/libjpeg

Compression speed is 7 to 8 times faster than TJPegImage, I'm not entirely sure vs IPP (they claim to be in the same ballpark).

#61 Fast JPEG decoder » Fast JPEG encoder » 2013-11-29 10:01:24

Eric
Replies: 3

Any suggestions?

This is to generate a lot of JPEG files on the fly server-side.

Eric

#62 Re: Other components » SynCrypto, HMAC and doing it "right" » 2013-09-13 07:04:47

I was under the impression that a known or predictable nonce / salt was as good as no salt from a brute-force hacking point of view, for the same reason that a salted password hash with SHA256 won't be enough to secure password shorter than 8-9 characters from a GPU brute-force crack if the salt is known and SHA256 is not applied thousands of times.

I've read that given the GPU perfs, an ASIC chip could likeley brute-force a salted hash password up to 10-12 characters passwords (numbers, upper and lower case characters and the common punctuation symbols) in a short time frame, and that this was the reason why even salted password databases were hacked these days.

But that may not apply to the situation here smile

#63 Re: Other components » SynCrypto, HMAC and doing it "right" » 2013-09-12 08:09:48

ab wrote:

But this is still a client-defined nonce, so IMHO this is not the weakness of the algorithm.

Didn't you said on the server side that a value derived from GetTickCount is used as well?

#64 Re: Other components » SynCrypto, HMAC and doing it "right" » 2013-09-10 14:29:37

I observed Random() has a similar entropy to real data

I've observed the opposite (http://delphitools.info/2011/12/13/pimp … -xorshift/)

On Server side, we use a simple value derived from GetTickCount, which will be valid for about 5 minutes.

What about using RDTSC? It's wildly varying, especially on machines with multiple processors.

On Client side, TSQLRestServerAuthenticationDefault.ClientSetUser() uses SHA256(NowToString) which does a pretty good job.

Wasn't the randomness of it quite low? There were only 86400 different hash values possible per day, and they are predictable long in advance.

I'm a bit wary of pseudo-random generated from time-based seeds at the millisecond level, since the machine time is usually known at that level of precision (these days, most machines are time-synchronized so they're typically within a second of the reference time).

While GetTickCount is a bit less predictable since it depends on the time the machine was last rebooted, it doesn't evolve very fast, and for Windows servers, you can make a good guess based on the latest critical windows updates release dates.

Anyway, my old quad-core CPU can f.i. compute 6 million SHA256 hashes per second with SynCrypto, that's enough to brute-force the whole 42 days range of GetTickCount-based salted hashes in about 10 minutes, and a GPU brute-forcers could scan the whole range in a matter of seconds.

I.FromNow;
inc(I.Value,GetTickCount+PtrUInt(Sender));

Given the above, since I.FromNow will be guessable, GetTickCount range is limited, so the PtrUInt(Sender) is the only portion that strengthens the nonce, but the range isn't that huge and similar values will occur between runs of the executable (since the TSQLRestClientURI instance size is rather large, there is a good change it'll be allocated from a highly-aligned sub-allocator block in the memory manager)

#65 Re: Other components » SynCrypto, HMAC and doing it "right" » 2013-09-10 10:30:29

Thanks. Client time stamp looks like a simple enough varying salt to validate.

I suppose some server-provided salt could also periodically be passed down to the client in the encrypted message to provide further strengthening.

What do you use for generating nonces in the field? The tests in mORMot use the Delphi Random function which is very weak and Randomize seeds exclusively on the machine time.

#66 Re: Other components » SynCrypto, HMAC and doing it "right" » 2013-09-09 15:26:51

ab wrote:

I would rather change the AES cypher key for every request, adding a random nonce at the beginning of the stream, then using it as salt for every AES key computation.

I see, even though the first AES block of a message is always 100% new random, and that random carries over the rest of the message through CFB, a message is "correct" in isolation and thus can be replayed.

However, that raises another question, to avoid the replay, it means that the nonce must be provided by the other side of the communication channel? Ie. for a client to server message, the client would have to use a nonce provided by the server, and vice-versa? (otherwise unless the server caches recent nonces, the client could replay by reusing the same nonce?)

#67 Other components » SynCrypto, HMAC and doing it "right" » 2013-09-09 12:21:05

Eric
Replies: 10

Just a small post to ensure I haven't missed something obvious and I'm using everything "right"

The goal here is to establish a communication TCP channel, authenticated and encrypted by symmetric keys.

First data I send is a nonce of 16 bytes of random, followed by the HMAC_SHA256 of the connection key (implementation below) with the nonce as message. This is used to authenticate the client-side of the connection.

procedure HMAC_SHA256(const key : RawByteString; msgPtr : Pointer; msgLength : Integer; var result : TSHA256Digest);
var
   i, n : Integer;
   pad : array [0..31] of Byte;
   sha : TSHA256;
   firstPass : TSHA256Digest;
begin
   n:=Length(key);
   for i:=0 to n-1 do
      pad[i]:=$36 xor Ord(key[i+1]);
   for i:=n to High(pad) do
      pad[i]:=$36;

   sha.Init;
   sha.Update(@pad, SizeOf(pad));
   sha.Update(msgPtr, msgLength);
   sha.Final(firstPass);

   for i:=0 to n-1 do
      pad[i]:=$5c xor Ord(key[i+1]);
   for i:=n to High(pad) do
      pad[i]:=$5c;

   sha.Init;
   sha.Update(@pad, SizeOf(pad));
   sha.Update(@firstPass, SizeOf(firstPass));
   sha.Final(Result);
end;

Then for the rest of the stream, I'm using a TAESCFB, where the key is the output of SHA256Weak of the connection key (in case the users entered a weak key).

The initialization vector is static, and the TAESCFB is created only once for the whole duration of the connection, *but* each message sent down the wire is pre-padded with 16 bytes of random (new random generated for each message), and those bytes are ignored on the other end. The messages themselves are made of compressed content followed by a simple CRC32.

The random bytes for nonce & padding come from CryptGenRandom, and are further XOR-ed by a weak random function based on RDTSC, QueryPerformanceCounter & GetTickCount (to minimize vulnerability to automated hacks in case a weakness in CryptGenRandom were to be uncovered).

Anything obvious I missed?

#68 Re: mORMot 1 » How to clone mORMot repository? » 2013-06-25 06:53:29

Is anyone maintaining a standard public repository for mORMot?

git, svn, or anything else would do, or a bridge from fossil (like git-svn does between svn and git).

Currently I'm manually synchronizing with an internal SVN, but that's labor-intensive, and of course all the check-in history is lost (I end up with just "updated from mORMot" and similar comments of mine).
Also for open-source projects, it's a little bit complicated to have dependencies to mORMot, as the zip downloads are impractical, and fossil requires login/password, so everyone ends up with more or less outdated forks...

#69 Re: mORMot 1 » 64 bit compatibility of mORMot core units » 2013-03-11 07:32:45

Nice job!

64bit compiler is quite stable IME, but the 64bit debugger can be a bit more problematic (at least in XE2)

A lot of the 64bit RTL is quite less efficient, several fastcode routines and previously (old) well-thought out RTL asm routines were replaced by Pascal ones that suffer from a mix of poor implementation/algorithmic choices and compiler optimization limitations. So comparatively, the Synopse routines should be even more preferable in 64bit.

#70 Re: mORMot 1 » Smart Mobile Studio mORMot class server » 2013-02-14 14:11:59

ab wrote:

I'm currently fighting against UniDAC + Zeos database backends, to integrate them with our SynDB classes.

Impressive stuff!

ab wrote:

Now, back to SMS. big_smile

Following this from afar at the moment (spare time goes into improvements & fixes for 1.1).

With 1.1 there is some RTTI capability in SMS (class attributes, reading & writing published fields, invoking published properties getters & setters), it's rather raw and not wrapped up, but it's there smile

#71 Re: mORMot 1 » SQLite3 performance: .obj vs .dll » 2013-01-16 09:00:21

h.hasenack wrote:

If I'm right, putting the DLL in the same folder as your executable will make it find 'first', independent of other SQLITE3.DLL's that may be on the system

If you use dynamic binding, you can load a specific DLL file in any particular path (it doesn't even have to be named '.dll').

I've used that to bundled DLLs as resources of EXE, then on startup they're extracted to the temp directory and loaded from there. If you create the DLL file with the temporary flag in Windows, it doesn't even really get written to the HDD, and you can use file locks to prevent other apps from accessing or modifying it.

That sidesteps the DLL and Windows built-in DLL resolution entirely.

#72 Re: mORMot 1 » SQLite3 performance: .obj vs .dll » 2013-01-11 06:49:04

What other compilers produce Delphi-compatible obj? I quickly looked a while ago, but without much success, if one of the top grade C compilers could be used, that could indeed be convenient.

FWIW the bundling of the dll in the exe is what I've been using for a while, there are two ways to do, one is to simply extract the resource to a temporary file (with a random name, that windows cleans up automatically), this works fine IME, never had any issues with anti-virus with it.
The other is to map the dll directly from the resource. I haven't tried it, this avoid the need to extract anything but requires some low-level wizardry.

#73 mORMot 1 » SQLite3 performance: .obj vs .dll » 2013-01-10 10:51:18

Eric
Replies: 20

I've ran a few tests between SynSQLite3 (that uses the .obj compiled by bcc32) and the "official" SQLite3.dll (3.7.15.1 on both sides)

The DLL is obviously compiled with a better C compiler, and it is executing queries about 25% faster overall.

Are there any plans to being able to use the dll instead of the obj? The dll could also be bundled as resource, and extracted as a temp file on startup, to avoid external dependencies)

#74 Re: mORMot 1 » Leaks in SynSQLite3 » 2013-01-10 10:19:02

By stateful I mean when you want to use the websocket not to push notifications, but to establish a connection to the server in which the actions related to a frame sent through the websocket aren't fully defined by that frame, but also defined by previous frames, and where that state isn't shared with other websockets (like in FTP or SMTP f.i.).

That makes a it a special case where the group consists of a single websocket (and then you only have to generate a unique name for the group, using Time+Random or whatever)

The concept of "client" wouldn't be part of the mechanism, it would be something you would add on top, and same goes for multiplexing on the same websocket.

#75 Re: mORMot 1 » Leaks in SynSQLite3 » 2013-01-10 07:39:47

For classic client-server I don't think WebSockets are really useful, as the browser will maintain connections (especially over SSL), and WebSockets frames have packaging as well that main not be wholly more efficient (unless you have large cookies...).

However WebSockets works well for pushing content and notifications, where it will have less server overhead than long polling, and less latency than periodic polling.

What I have in mind for websockets would basically be to attach them to a "named group", each named group would be linked to a processing (a script f.i.) and a set of in-memory properties. Any other server-side processing could post messages/content to a "named group", which would then be dispatched to all clients on the other side of the websockets.

This should AFAICT solve the need for push notifications very simply: just attach all the websockets to the same "named group" / notification channel.
And individual (stateful) websocket connections would be named groups with only one websocket in them.

#76 Re: mORMot 1 » Leaks in SynSQLite3 » 2013-01-09 13:34:49

chapa wrote:

I can provide support for XE3.

XE3 uses could be problematic due to the dotted namespaces, though as long as the aliases work, that should be okay (ie. not looking forwards to ifdef's in the uses clauses...)

chapa wrote:

Do you plan to add WebSockets support on HttpSys2 server side?

Eventually yes, though the relevant functionality was added in Win8/Win2012, and I have access to neither at the moment...

#77 Re: mORMot 1 » Leaks in SynSQLite3 » 2013-01-09 11:55:00

chapa wrote:

Do not know if here is the place to report, but know Eric will see it.

You can post in the issue tracker (http://code.google.com/p/dwscript/issues/list)

chapa wrote:

Eric, in order to compile the server (Delphi XE3) I have to correct following

This will require some ifdef'ing: in XE and previous versions, all those functions are declared as "var xxx : cardinal".

As I don't have XE3 to test, what should those ifdefs be?f.i. does this work in XE3?

   {$if CompilerVersion < 24.0} // XE3
   completionKey : DWORD;
   {$else}
   completionKey : DWORD_PTR;
   {$ifend}

#78 Re: mORMot 1 » Leaks in SynSQLite3 » 2013-01-09 09:49:04

Updated & simplified the wrappers.

I've added UIB driver, it's a bit heavier in terms of code size and dependencies, but full-featured and shows it's simple to wrap just any db layer.

#79 Re: mORMot 1 » Leaks in SynSQLite3 » 2013-01-08 15:23:32

Works all right AFAICT once the 'protected' are replaced by 'private' at the lines mentioned by Bojop

#80 Re: mORMot 1 » Leaks in SynSQLite3 » 2013-01-08 07:41:27

ab wrote:

But I was not able to find out a similar issue in this case.

It was with SynDBODBC.

Compiler bug confirmed: issue comes and goes when building/rebuilding... and that's an "object" as in the other bug you linked.

Though since it uses inheritance and virtual methods, it can't be replaced by a record, but has to become a class, which means various other changes in the rest of the code to create/destroy manually, but that's probably the only option as compiler support for "object" is becoming weaker and weaker.

#81 Re: mORMot 1 » Leaks in SynSQLite3 » 2013-01-07 15:47:49

ab wrote:

Could you send us your FreeIB layer? webcontact01 at synopse dot info

Sent.

ab wrote:

Why did you specify SynDBODBC for DWS?

because that's the only unit I looked at initially wink
I've re-based on SynDB, I'll commit so you can take a look.

I'm getting a leak in simple statements, apparently TSQLDBStatementWithParamsAndColumns has a fColumn field of TDynArrayHashed that isn't freed, and that's the only leak I'm seeing... the FastMM4 log says

This block was allocated by thread 0x544, and the stack trace (return addresses) at the time was:
40495D [System.pas][System][@ReallocMem][3935]
409932 [System.pas][System][@DynArraySetLength][26579]
87A8C7 [SynCommons.pas][SynCommons][TDynArrayHashed.AddAndMakeUniqueName][19969]
8F0ED6 [SynDBODBC.pas][SynDBODBC][TODBCStatement.BindColumns][1082]
8F2393 [SynDBODBC.pas][SynDBODBC][TODBCStatement.Prepare][1441]
8F3B4A [dwsSynDBDatabase.pas][dwsSynDBDatabase][TdwsSynDBDataSet.Create][227]
8F3ABA [dwsSynDBDatabase.pas][dwsSynDBDatabase][TdwsSynDBDataBase.Query][211]

#82 Re: mORMot 1 » Leaks in SynSQLite3 » 2013-01-07 09:42:01

Firebird usually, Oracle & MS SQL for larger uses or when the customer already has licenses/admins, and SQLite for everything else.

For Firebird we used to use IBX a long time ago, but due to various bugs and bloat, we've fallen down to the FreeIB layer that IBX was built upon, with a few fixes, it's still running smoothly. There doesn't seem to be any official place for FreeIB anymore, or I would have published the fixes (even though these aren't extensive, and are essentially related to adding Unicode support and fixing minor blob issues), though I'm not sure what the Borland license headers mean (and so if those files are really redistributable from the Borland version, if the original open-source version should be used, or if headers should be remade from scratch from the C headers).

#83 Re: mORMot 1 » Leaks in SynSQLite3 » 2013-01-07 08:34:19

Btw, just added SynDBODBC wrapper, worked like a charm smile

#84 Re: mORMot 1 » Leaks in SynSQLite3 » 2013-01-06 14:00:56

ab wrote:

If I were you, I would stay away from Zeos, or use DBExpress components.
The best solution could be some abstract interfaces, then several implementation classes targeting various DB providers.
I suspect that you will find out how SynDB*.pas unit are easy to work with.

Okay, good to know, I'll go directly for SynDB then!

We've been evolving our own DB connection layers over the years @work, so I haven't used any of the bundled Delphi DB components in years (except to test occasionally... and shake head in disbelief). Having a new source of fast & tested drivers is good!

Also you mentioned ORM, I've not looked into how you're tying mORMot to the servers yet, f.i. to have a ".dws" handler cooperate with a native Delphi mORMot handler.
I guess you're supposed to subclass, check the request, and then call inherited if the request is not handled? (if so, there would be nothing special required for me to make the dws http server compatible with other Delphi-based mORMot handlers)

#85 Re: mORMot 1 » mORMotService » 2013-01-06 13:43:24

Ok, I'll look into what's wrong.

At some point in time the Delphi TService support wasn't available in all Delphi editions, so that's why I went for mORMotService (and your versions was going to be lighter and more "fixable" anyway).

#86 mORMot 1 » mORMotService » 2013-01-06 06:03:38

Eric
Replies: 3

Is it just me or is service shutdown a bit "brutal" and you get messages when shutting down from the service manager? (Services.msc)

@ab: in dwsWindowsServices I added a couple features you may want to integrate - so I can remove my intermediate class wink - one is the ability to set the service description, the other is to detect is the exe was launched by the SCM. This allows to make executables that can work both as application and as service (like DWSWebServer demo).

#87 Re: mORMot 1 » Leaks in SynSQLite3 » 2013-01-06 04:46:22

Thanks smile

ab wrote:

For the HTTPS.SYS API version 2, I will certainly integrate it to Synopse, but perhaps with some syntax differences (e.g. using enumerations and sets for flags, instead of plain C constants).

You might want to start from the xxm header translation instead (http://sourceforge.net/p/xxm/code/240/t … tpapi2.pas), it's more complete.
I only found it while I was almost done... and had hacked my way through the minimal header requirements (so I don't have everything in the http.sys 2.0)

ab wrote:

Note that some of your code already do not include fixes made for 64 bit compilation, I committed last days.
This is the limit of forks. wink

Well it was either fork or hack SynCrtSock to death because some methods and types were buried in the implementation section smile
And hacking to death would have been far more troublesome to keep sync'ed with your official version.

In the next release you'll split SynCrtSock in many smaller/simpler units so a new HttpAppi server can be subclassed more easily?

ab wrote:

A TDataSet is a start, but we may benefit of something stronger, like an ORM.

I went for the minimal interface that would be both functional and allow wrapping various db techs smile
Blob support is still MIA and some things are going to change (DataType will become an enum, a DeclaredType with the raw db type string, and probably some minimal standardized metadata queries)

I currently have a wrapper for SynSQlite, our proprietary drivers, and I would like to add some more open-source drivers wrappers, like for ZeosLib?
I've never used ZeosLib though, but I've spotted it in Synopse directories, and noticed some recent updates to it. This would be mostly to add support for the usual suspects (MySQL, SQLServer, Oracle, Frebird & PostgresQL).

ab wrote:

What about your direct SQL statements in .dws files?

Haven't started on it just yet, as I was wrapping up the server & setting up the minimal DB interfaces.
But this is certainly something I'll give a try, coupled with some JSON connector enhancements and beig able to expose script functions to SQLite, you could use it write things like

JSON.stringify(select field1, MyFunc(field2) from someTable where field3=@myVariable)

Which would be not just convenient, but also would catch SQL syntax errors at compile time.

#88 Re: mORMot 1 » HTTP Server / DWScript » 2013-01-04 16:43:58

First version is out there smile

You'll need trunk latest DWScript & Synopse files, Win2008 or Vista or better (http.sys 2.0 requirement)

I made precompiled binary with mini demo site for those that want to test directly:
http://code.google.com/p/dwscript/downl … Server.zip
For config options and server doc, see http://code.google.com/p/dwscript/wiki/WebServer

At the moment telling notepad++ that .dws files are highlighted as html works "almost" well enough.

Demo includes a basic memory + cpu usage monitor, a minimal DB (SQLite) exemple, and some special cases.
Throttling (CPU and Bandwidth), SSL and NCSA logging are supported too.

#89 Re: mORMot 1 » Leaks in SynSQLite3 » 2013-01-04 14:54:26

Nice! Thanks smile

While I have your ear, my I abuse by asking for a FieldDeclaredTypeS? (sqlite3_column_decltype...)

function TSQLRequest.FieldDeclaredTypeS(Col: Integer): String;
var P: PUTF8Char;
begin
  if cardinal(Col)>=cardinal(FieldCount) then
    raise ESQLite3Exception.Create(RequestDB, SQLITE_RANGE);
  P := pointer(sqlite3_column_decltype(Request,Col));
  result := UTF8DecodeToString(P,SynCommons.StrLen(P));
end;

#90 Re: mORMot 1 » Leaks in SynSQLite3 » 2013-01-04 13:39:11

Btw, any chance of supporting the WideChar variants in SQLite? ie sqlite3_bind_text16, sqlite3_column_text16, etc. or are they missing from the .obj?

#91 Re: mORMot 1 » Leaks in SynSQLite3 » 2013-01-04 12:56:01

Thanks for the extra check!

#92 Re: mORMot 1 » THttpApiServer and max upload size » 2013-01-04 12:48:53

1) good point, eliminated

2) yes, one of the key reason behind the move to http.sys 2.0 is that authentication is supported in the kernel driver (not just faster and less code required, but also less trouble with service/application access rights)

#93 mORMot 1 » Leaks in SynSQLite3 » 2013-01-04 10:14:52

Eric
Replies: 33

I'm getting memory leaks with SynSQLite3 each time I open or close a DB, f.i. with just

procedure Test;
var
   db : TSQLDatabase;
begin
   db:=TSQLDatabase.Create(':memory:');
   db.DBOpen;
   db.DBClose;
   db.Free;
end;

The leaks come from sqlite3_memory_highwater through TSQLDatabase.DBOpen according to FastMM.

These are not one-time leaks, the more you call the above procedure, the more you leak. Any solutions?

#94 Re: mORMot 1 » THttpApiServer and max upload size » 2012-12-26 22:33:07

I've got it working now, with logs & bandwidth throttling too (haven't tried authentication yet, nor any of the other properties). Most trouble I had was with a MS documentation bug on MSDN.

If you want to have a look, you can find the relevant files in DWScript SVN under Libraries\SimpleServer, though the rest of the demo in the SVN is WIP and doesn't use them yet, once I get everything in working order, I'll commit the rest.
Btw, I made a SetCompressHeader optimization that should be easy to backport (eliminates the temporary string).

Since library can be loaded dynamicaly, we may be able to include both entries if available.

Yes, though the code above currently makes no attempt at distinguishing between v1 & v2.
The snags with supporting both will be a change in the request/response record (they added a couple fields), and having all the v2 functions optional from v1.

That said, the changes from v1 to v2 are rather simple, with some code not requiring any change at all.

#95 Re: mORMot 1 » THttpApiServer and max upload size » 2012-12-26 09:24:12

FWIW I've started an experimental fork to see how far I can go with Http API 2.0 support, I'll post the relevant files in the DWS SVN.

#96 Re: mORMot 1 » THttpApiServer and max upload size » 2012-12-23 13:30:32

I've found a partial (but dirty) workaround by importing HttpCancelHttpRequest from http 2.0, and aborting the request when the headers have been received.
F.i. this will forbid any posts larger than 1kB

          if InContentLength<>0 then begin
            if InContentLength>1024 then begin
               //SendError(412, 'Content-Length too large');
               Http.CancelHttpRequest(fReqQueue, Req^.RequestId, nil);
               continue;
            end;

It's a bit dirty because the request is canceled, so you can't send a response.
The alternative is to just fetch all the content in a rotating buffer and discard everything as it comes in, this allows sending the error response, but then that means your incoming bandwidth will have been eaten, so the cancel may not be that dirty (and you can catch the error on the client side if it's a legit post attempt).

Delving into it, I found Http 2.0 API includes a lot of useful stuff, like kernel-level authentication, static cache, logging, etc.
It ups the requirements to Vista or Windows 2008 though, but looks worth it if you're going to front the server on the wild web (otherwise, it's not too hard to DDOS an HttpAPI 1.0 server by sending in large simultaneous posts that'll keep the THttpApiServer.Execute threads busy eating all the RAM).

Are there any plans to up HttpAPI to 2.0 level?
If so, maybe HttpAPI support it should be taken out of the SynCrtSock unit, so it becomes more easy to pick one or the other by just using the relevant unit.

At a minimum, having an OnHeaderReceived event would be nice, so the above header-related processing could be handled in our code.

#97 mORMot 1 » THttpApiServer and max upload size » 2012-12-21 20:45:07

Eric
Replies: 7

Is there a way to limit maximum upload size at the http.sys level? ie. before the Process event is called.

I'm mostly worried about limiting the amount of RAM attempts at large uploads could consume. I'm running a test server on a shoestring RAM budget, literally, think Ikoula's 1€ VMs and wanting to stay below 512 MB RAM smile

In IIS there are maxRequestLength and maxAllowedContentLength settings, what are the equivalent there? (quickly scanned the Http Server API, but couldn't find how you set them)

Also what about bandwidth limitations? (HttpServerBandwidthProperty)
Any body got experience with them?

#98 Re: mORMot 1 » HTTP Server / DWScript » 2012-12-19 11:20:47

mpv wrote:

3) bad performance under Windows virtual machine

Yep, noticed that.

Also it is single-threaded, and in my tests it reached 100% CPU utilisation of its core (ie. 25% on my quad-core), without having the Synopse web server maximized... so it was also measuring its own performance as a client rather than that of the server.

I tried to alleviate it by running it from different client machines at the same time, but that's not very practical.

mORMot is VERY FAST! smile

Yep! smile

Problem is, it's so fast we can't claim it's faster than the rest, because test clients aren't fast enough to differentiate...
Making a custom test client could alleviate that, but then it would raise issues of fairness of the test...

#99 Re: mORMot 1 » HTTP Server / DWScript » 2012-12-18 15:54:55

Any suggestions for a web server stress tool?

I had been using JMeter so far, but the current HttpAPI Server + DWScript is too fast on simple queries compared to JMeter, and I'm seeing a 10 to 1 cpu usage (10 for JMeter, 1 for the server), and I don't have 10 client machines to use to balance the client load smile

#100 Re: mORMot 1 » HTTP Server / DWScript » 2012-12-14 06:49:17

ab wrote:

Did your own server uses IOCP?

Initially it was using events & signaling, got changed a couple years ago when I introduced IOCP-based worker threads and futures (aka promises).
Currently our DB layer is asynchronous too, and a few background caching and UI tasks have been converted too.

I'm quite sure LZRW1 will be slower than our SynLZ implementation

I tested here, and indeed it is! well done!
The compression is also better in all scenarios I tested (sometimes not by much, but always better).
I've just replaced LZRW1 with SynLZ for the internal test middle-ware here, it should be seeing a few gigabytes of LAN traffic in the next days smile

Unless I misunderstood SynLZ is LZab? (lempel-ziv-arnaud-bouchez i.e designed by you?)

a hashing limitation makes SynLZ sometimes unable to pack continuous blocks of same byte

What does that mean exactly? That it will crash or corrupt, or just that the compression ratio won't be good?

Using a parameter defined as a class has a very low overhead, in fact (from real profiling on our stubbing routines).
I'll see how to implement it.

Thinking on it, maybe the current THttpApiServer class could remain in a similar or "low level no bells nor whistles" fashion, and a new subclass be introduced with the extra http response/request class?

This would also have the benefit of "opening up" THttpApiServer a bit for subclassing (currently it can't really be sub-classed, as all the logic is private or in SynCrtSock's implementation)
And with the above in mind, it would be nice if the Process event weren't called directly, but rather called from a DoProcess virtual method, with would facilitate subclassing and adding custom processing before/after/in-place-of the request (such as standard http logs)

Board footer

Powered by FluxBB