Montag, 10. September 2018

Where to do the Synchronisation?

While designing a new class/function there are some thoughts to do.

  1. Could it be useful to others?
  2. Could I uses it in an other Apps?
  3. Could it be useful to have it as TWhatever<T>?
So if one of 1-3 is true - I have a new class/function in one FDK-Unit or perhaps a new Unit at all.

Next thing is: Where would I like to execute this stuff - Main-thread or Background? If  the answer is Background the next question is how! With an existing threads or a new one? Should the User just place it into a TTask.Run?

Threading is a big part of the FDK and there are 14 Units at the moment dealing with threading. Some of them using a basic thread implementation from an other unit, some implementing own Threads because of special needs.

So for this blog post lets assume background operation, but every background execution has some point of interface into the Main-Thread. And here comes the question:

Where to do the synchronization? 


Let's have a little example:

Procedure Button1Click(Sender : TObject)
var
  LMemoText : String;
begin
  Button1.Enabled := false;

  TAsync
  {} .Await( Procedure
               begin
                 LMemoText := THTTPRead.URL(SomeURL); 
               end )
  {} .Execute( Procedure
                 begin
                   Memo1.Lines.Text := LMemoText;
                   Button1.Enabled := true;
                 end );   
end;

So the Await procedure is running in a thread, that's why I set a string and not directly the memo. The Execute procedure is called in MainThread to handle UI-Stuff. So the synchronization is handled internally. It could be different... But the is the common usage of this TAsync. I Could write it so: 

Procedure Button1Click(Sender : TObject)
begin
  Button1.Enabled := false;

  TAsync
  {} .Await( Procedure
             var 
               LMemoText : String;
             begin
               LMemoText := THTTPRead.URL(SomeURL);

               TThread.Queue(NIL,Procedure 
                 begin
                   Memo1.Lines.Text := LMemoText;
                 end);
              end )
  {} .Execute( Procedure
                 begin
                   Button1.Enabled := true;
                 end );   
end;

But in this example the synchronization is done twice...

Back to the question: Is the internal synchronization of the Execute part a good idea? In the example I think yes. 

Sometimes internal synchronization could be a bad idea especially if TThread.Synchronize is used and not Queue but in the next example even Queue did not help, and here is the reason:

Normally I would do any HTTP related things with a callback, but for this example I like to show a Modal-Call of an Async function, just for Demonstration.

Procedure THTTPRead.URL(Const AURL : String) : String;
var
  LEvent : TEvent;
  LResult : String;
begin
  LEvent := TEvent.Create(NIL,true,false,'');
  
  try 
    THTTPTAsync.URL(AURL, Procedure (Const AResult : String)
      begin
        LResult := AResult; 
        LEvent.SetEvent;  
      end);

    LEvent.Wait;
  finally
    LEvent.Free;
  end; 

  Result := LResult;
end;

Don't do this ;-) but if, then hope that the Result procedure is not called in a TThread.Queue, because this would be a dead-lock. If you have a Threaded or Async Class/Function use it always as it was designed for. 

On the other hand I hate to put in a TThread.Queue in every Call-Back that's why I often design an optional parameter.

THTTPTAsync.URL(AURL, Procedure (Const AResult : String)
  begin
    _Result := AResult; 
    LEvent.SetEvent;  
  end,false); // false = no sync

For better code reading perhaps rename the call like

THTTPTAsync.URL_NoSync(AURL, Procedure (Const AResult : String)
  begin
    // Whatever
  end);

or

THTTPTAsync.URL(AURL, Procedure (Const AResult : String)
  begin
    // Whatever
  end,TSync.No); // TSync = (Yes,No);

Honestly, I mostly just use a boolean, but I'll put it on my List for refactoring.

So with this approach I have the best of both...

Montag, 3. September 2018

App-Development, Cloud-Server and distribution to multi clients!

Cloud-Database.. (And many more...)


OK - It's just a computer at an other location - so what is this blogpost about?

It's about the next step form my last blogpost: Database and Serversyncronisation.
In many conversations to other developer, most of them want to build a mobile App that is kind of an Access Point to the data used by one or more  PC-Application(s).
At first - no Form from the Desktop App should be take into the mobile App!
Designing a mobile App with a "smaller" UI, to achive some of the basic functionalities that are necessary to handle the data, is not a big deal. If you are new to FMX, it's just takes a while.
So how could you overcome the problem of not reinventing the wheel and perhaps reuse the work for the next App, too?
BTW: Thank you for reading my blog… This blogpost is again just for advertising my Firemonkey Development Kit. ;-)  (sorry, linked post -  is not translated, yet)
Best practive for the development of libraries like my FDK is as always : "Eat Your Own Dog Food".
And I can promise  -  I eat it every day! It saves me a lot of time and things are always easier.
The next Version of the FDK would have some new plugin's.
  1. Simple ORM
    Just create a class with some Field-Attributes and you'll get a Database with a Table to store the Fields. (nested Tables are also supported, for multi entries like 1-n Bankaccounts or 1-n communication - subtables )
  2. CRUD IO
    You like the easy CREATE / READ / UPDATE / DELETE access of your data. Set some Class-Attributes and use the simple ORM model to build your application.
    An Easy SQL-Producer is included.
  3. MVVM 2.5
    How to Access the Data? Just bind (in Code) the View to your ViewModel/Model (CRUD->ORM) class and you can easiliy display the Class from (1) on your View.
  4. All your Events - PropertyChanged - are auto-connected with one line of code. You can multi-connect data to 1-n UI-Fields. Data->View, View-Data and Bidirectional, with optional converter functions. There is no need for a special UI-Component and there is nothing to drop onto your form. Like described in this post.
  5. Async Await
    Perhaps you know Async Await from C# - I have a "lite" Version for UI/Async/Threading tasks included.
  6. Async Threading Command Queue
    The Threaded-Command Queue is for SQLite/Embedded Databases that can only handle one Thread/Connection at the time. Define your Data-Access-needs and just call them by Name. The Queue will handle all your calls one after another - or if you have some important stuff to do, you can call it prioritized.
  7. JSONStore-Server
    A "just use it" Unit to store every data you like in JSON Format on your server database.
  8. REST-JSONStore-Client
    To handle the JSONStore Server-Side you get the Units to handle all transfers/updates/locking/rebuild features to do your data-exchange with the Server or/and multi Clients. Of course this module has the Async Threading Commands for module (6) included to do everything in the background.

So what is the deal? My goal for mobile App creation was:
Create your UI - create your Classes - just set some Bindings and Field-Attributes. Nothing to drop on your form and nothing to set in the object-inspector!

Just write some uses and have fun...








Samstag, 18. August 2018

Database and Serversyncronisation

As a developer I would like to program fancy stuff, but in 90% of my time I only transfer Data from here to there...

Edit -> Memory -> JSON -> REST -> JSON -> Query -> Database.
or
Database -> Memory -> Form -> Memory -> Database.

Collect data here, combine with data from there, ask the user and write it back.

Sometimes

Client 1 : Form -> Database -> JSON/REST -> Server -> Database;
Client 2 : Server -> JSON/REST ->  Client -> Database.

Comparing problems on a single non Server App against a Multi-Client-, Multi-Server-Environment you can find pitfalls on many procedures.

With all the mobil devices you normally have more the one location of your data and if you provide a mobil solution to your desktop application, the user expects a synchronization over the "cloud".

I've always developed it again and again for every new App, but why?

My cloudstore is useing the same database structure as the desktop and the device database was often nearly the same. So to store the data into the Server database I had to develop it each time.

For my application there is no need of a webinterface, so the server must not have access to the actual data.

So finally I've developed a Class/ORM/CRUD/Cloudstore interface that can be used by all of my (FDK) Applications. Both interfaces for Client and Server are in the next FDK-Plugin. so stay tuned.

So next time more fancy stuff and less hassle with the data.



Mittwoch, 18. Juli 2018

Delphi & C++ Builder Community Editions are online...

For many years a Community Edition was missing…
 
Now it is out:
 
 
 Registration and download:
For the moment you could not install both in one VM.


Info from embarcadero.com:
Embarcadero® Delphi 10.2 Tokyo Community Edition is a great way to get started building high-performance Delphi apps for Windows, mac OS, iOS, and Android. Delphi Community Edition includes a streamlined IDE, code editor, integrated debugger, two-way visual designers to speed development, hundreds of visual components, and a limited commercial use license.
To learn more about Delphi Community Edition Click here

Freitag, 6. Juli 2018

IIS an Plugin-loading

The Loadlibrary Problem!


Since many many years I do all my Web stuff with ISAPI.DLL's on one of my Windows Server. Starting with the support of ASP.NET in Delphi I use only ASPX and background code for the webdesign. (Only one project I've done with VCL for the Web.)

The benefit with ASP.NET was, that you do not have to restart the IIS to change the code behind.

There was an ISAPI Loader from egg-Soft that was able to update the working DLL on the fly, if you upload your dll as name.upd - works great for many years.

After updating the server to 2008 R2 this loader did not work anymore… So every time I had a new version of my DLL's I had to stop and restart the IIS. Normally a 1 second interruption, if your IIS is only handling local stuff or just producing websites.

But since 5 years I have a webservice for my customer running, that depends on an external service. The service sometimes takes some time and I have many request. So stopping and restarting the IIS take 5-25 seconds and that is bad for my customer. Every development took place only at night.

Inspired by the EMBT Rad-Server project I want to build my own Service (perhaps as part of my FDK)

Project/New/ISAP.DLL but this time with loadable and unloadable plugins. My idea was - I provide you with the hard stuff and you only have to write you business code.

The FRS - Firemonkey REST - Server was born.

 
Or Fast-Remote-Service? Because in some parts the Firemonkey part in FDK is wrong, because you could use it in VCL, too - I do not have finally considered the Name. 

A working demo was done in one day (2016) - LOCAL - but my first try on a real server - nothing. No plugin could be loaded, only the root admin things are running. No idea where to look. But as always: While starting a new project - there was no time for digging into this problem.
 
Sometimes before I build a new ISAPI.DLL I'll tried some Ideas (2017), but after a few tries I build a new ISAPI.DLL with copy/paste from the last one.
 
But not this time. (2018) After some chatting with MVP Andrea Magni (MARS-Curiosity) and after some logging - i found the problem. Loadlibrary did not come back and crashes the AppPool. No Idea. Andrea provided me a Link. DLLMain - What? I have no DLLMain so I did not see the hint at the first read.
 
The hint was : do not call Loadlibrary in the Main-Thread. From my point of view every ISAPI.DLL is loaded by the IIS and with every request the IIS creates one thread of it.. So never in the Main-Thread.
 
After a few tries with LoadLibraryEx - I tried to compile my DLL's in 64Bit so this WOW thing is not necessary. LoadlibraryEx worked but no handle or a handle but nur GetProcAddress.
 
After some googleing for a new version of the Egg-Loader I came back to the Best-Practices Link and finally found "Call LoadLibrary or LoadLibraryEx (either directly or indirectly). This can cause a deadlock or a crash." OK - This is the problem - and perhaps same for the old egg-loader - and now?
 
Don't do this and don't do that - but how to load a DLL?
 

You remeber : NOT IN THE MAIN THREAD!

 
After a simple TTask.Run() around my Plugin-Loader everything works fine. Perhaps I will create a normal thread for this task. But for the moment it's working (that are the good news) - the bad news are : Now I'm able to build all that Stuff that is on my wish-list and I have no excuse not to do it) ;-)
 
But as always - not enough time.
 
 
 

Montag, 25. Juni 2018

German CodeRage 2018

Nur eine kurze Erinnerung: CodeRage 2018 am 26.06.18.

Meine Session ist 18:00 Uhr - 18:45 Uhr

Fluiddesign und andere Techniken um sich den Programmieralltag zu erleichtern.

Ab 18:45 Uhr bin ich für FAQ's online!


Hier der Youtube-Link.

Sonntag, 20. Mai 2018

Formatting Sourcecode

Formatting Delphi/Pascal Sourcecode is an interesting  topic.

Take 10 developer and let them all hand-formatter some sample source-codes and you will get 10 different results.

You disagree?

Most developer has developed their own style in formatting sourcecode, because they are working alone and nobody else would see the code. Perhaps you are new to Delphi and used another programming language for many years. I can not remember what Delphiversion was this first with an included formatter CTRL+D. Perhaps before that, your are using an IDE plugin or external program.
 
If you are working alone - do whatever you like with your source-code, but if you have to work together with other developers in a team - it's time to think about "your" formatting.
 
Some developer like many empty lines and indent nearly everything or want to have a description with a Date, Name and Copyright over every method. Other developers hate empty lines and only ident one space.
 
Perhaps you have the "begin" at the end of line and the "end" at the first position like:
 
if A > B then begin
  foo(42);
end;
 
But since the IDE has Castalia or perhaps your are using a third-party-tool you got the funny colored helper-lines to show the corresponding  begin-end's, it is better that begin-end has the same ident.
 
Is there a right way to format your source-code? You may have the standpoint - only the default formatter-settings are the right way.
 
Keep in mind - if you are writing a program, you will read more sourcecode then you write or in other words writing sourcecode is not the trick, writing sourcecode that could be read easy and by other developers too, is the goal.
 
Of course the formatting is just the start, next topics are caps, spaces and naming. There are so many rules out in the field.
 
Class fields has an "F" at the beginning, parameters an "A", local var's an "L". Perhaps you like to mix your local language with English (better not). Are you rename all your visual controls?
 
Label1 -> lbName
Edit1 -> edName
Edit1 -> NameEdit
 
Do you like long var-names "Name_of_the_person" ( hope not with "_" )
 
So where to start?
 
In the next day's I will try to introduce some of this rules to a team of four very different developers. Let's see if I can crate a set of rules that everyone can live with.
 
But that will eventually be a topic for an other blogpost.