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.
 
 
 

Donnerstag, 26. April 2018

MVVM 2.0 - I did it my way.

If you like, you can compare this with one of my older posts from 2016: MVVM - Or what I think MVVM is.  (Translated)

Why MVVM?

  • Because it’s cool and I’m a geek
  • to show – I’m better than other developers
  • so nobody else could maintain the code

no – perhaps – NO!!! Just joking!

Because we like to
  • separate forms from code
  • to get better maintainable code
  • have less-hardcoded dependencies
  • to be able to test the business logic
  • to test the workflow

Sure? Are you writing tests? If not – stop reading…
 
But perhaps you like to develop code you can use again in other applications…
 
Ask 10 developers to explain MVVM – at first; you will get a picture from dotnetpattern.com, msdn.microsoft.com or wikipedia.org, then everybody tells you: “This is the pattern and “so” it has to be implemented”
 
OT: Like many other patterns… You have to follow the rules of this 4 guys and the book from 1994! More than 500.000 copies of the book have been sold – not so bad at all…
 
Back to MVVM - If you ask for the details, you will get 10 ideas how to implement it.
 
But… We are Delphi developer – why should we try to implement things as Microsoft did in .net? Because this is the right way?

Let us dive into:
The core elements are View, Viewmodel, and Model. At the beginning, you could trade a TForm as the View, but this is not the same. A TFrom could be the container for many views at the same time. For the moment, we say TForm = View – the key things of MVVM are the bindings or better, the communication from Viewmodel to View and back. (And perhaps to the Model)
 
If we follow the rules – the view should have no logic, the Viewmodel is responsible for handling the view-logic and converting the data to the View and the Model contains the data. (hope this is right) I never took this approach.
 
Our view is not a stupid xml-only-description of visual controls. Our controls always have their own logic, we have styles and animations, able to do onMouseover/down/up things. Trigger doing fancy stuff.
 
The Model is dealing with the data and the Database, too? I don’t think so. What is a database?
 
Neither my ViewModel nor my Model know what a database is. The Models gets an interface to store or load data – without knowing where it ends.
 
How does the communication work?
 
The Model changes some data and now the ViewModel wants to inform the View or perhaps all Views, about this change.
 
At first, we need a Multicast event to inform more than one View about the new data. So every view has to sign in for the event. Now the Viewmodel could send a PropertyChanged Event like:
 
PropertyChanged(PersonNameProperty);

Every view – that is able to show the change, gets the Event and could ask the ViewModels Property PersonName.

What?

PersonNameProperty is defined as:
Const PersonNameProperty : String = 'PersonName';

Use Consts and no magic String so we always have the right typo. OK…That is good, but:

In the View we end up in a

procedure PropertyChanged ( Const APropertyChanged : String);

Comparing with many If then else constructions (first bad thing) and because we have a const in the Viewmodel, the reference is not the same so the string-compare must compare all chars. (second bad thing).
 
If we have a huge view (yes we could perhaps split it) we and up with a too long comparing procedure.

Since Windows 3.1 - in the early days – Messages are send with the content or at least with a pointer to the content.
 
So why are we just sending change “hints”? This is like sending a SMS – I have news call be back, instead of “I will be late, arriving at 8pm”.

Sending Strings is good for testing. Eg: A property change of PersonName := 'NewName'; should fire 'PersonName' – I tried Const ID’s  like Const idPersonName : Integer = 42; Not so good for testing but you can use a case at the View.

I don’t like to repeat on every Property:
 
begin
  if FPersonName <> AValue then
    begin
      FPersonName := AValue;
      PropertyChanged(PersonNameProperty);
    end;
end;
 
Same in every setter.

 
Then to the View:
if APropertyChanged = TPersonViewModel.PersonNameProperty then
  PersonName.Text := FViewModel.PersonName;

I first implement the MVVM Pattern the MS-way, but if you think – “To much writing” or “I did not test my code” – you are right and of course, debugging is not so easy, too…


In fact, development time takes a bit longer. This extratime cut’s down my Test-writing-Time… (Bad thing three), because I love TDD.

It is faster if you could use the same Model or perhaps the Viewmodel in another project, but that is another story.
 

These problems lead me to “my way” MVVM 2.0…


We have attributes and the RTTI!

I think: The best way to use a pattern is if the pattern is not so far from you normal workflow.


I like to design my Forms and so my Views as Forms, too – Frames are bad and often leads to problems with the IDE. So SubViews are Forms with a TLayout-Container that parent is mapped to the target-parent at runtime.

My new workflow is:
  1. Create a Form/View
  2. Change Class(TFrom) to Class (TMVVMForm) / or Frame for SubViews
  3. Put attributes at FormControls like [ViewModelLink] PersonName : TEdit;
  4. Create Procedures with attributes like
    [PropertyChange]
    Procedure PersonNameChanged(Const AValue : String);
  5. Register the Form at the ViewLocator with the necessary ViewModel
  6. That’s it.

In your NavigationService you could get the View from the ViewLocator for a given ViewModel and an optional Name. On Creation the View connects all bindungs and propertyChanges.
 
 
You like to change Names? All attributes take optional name parameters. For:
 
 
[ViewModelLink(TPersonViewModel.PersonNameProperty]
Edit1: TEdit; // Better rename this!
 
 
Now to the ViewModel:
 
  1. Create a class TPersonViewModel = Class(TRootViewModel)
    I don’t like ViewModelBase as Name – it sound like a database for ViewModels…
    All my DBClasses ends with Base – PersonBase not DBPerson!
  2. Define your private Fields as
    FPersonName : autochange<string> // FPersonName : String
  3. Property PersonName : String : read GetPersonName write SetPersonName;
  4. Procedure SetPersonName(Const AValue : String);
    begin // Auto-PropertyChanged if different.
      FPersonName.Value := AValue;
    end;
  5. That’s it.
 
 
Most of the stupid code writing is not necessary anymore and done in the background over the RTTI.
 
 
Of course, this is only a small part of this pattern, but now I can point my focus on the more advanced parts.
 
 
You like this approach? – Please leave a comment – if not…;-)
  

Mittwoch, 14. März 2018

Neural Network

Neural Network or Neuronal Network... Whatever...


Since many year's I want to test this kind of programming... But never had time for this.

You can find many videos on YouTube, but "all" are full of math or full of the wrong programming language. ( or both )

You can find some source files, but what is the minimum of LOC's you need?

For now: Less the 300 LOC in Delphi for a working network.

At the moment I have many ideas what I can do with this... But perhaps first dig into the next step:

Genetic algorithm.

I will include this in the FDK, if ready...

Best video I found: 

https://youtu.be/-zT1Zi_ukSk (C#)
https://youtu.be/KkwX7FkLfug
This, I take to just live code this - with many modifications - in Delphi - a little bit of debugging and it works. ( not much longer than it takes to look the video)

Dienstag, 20. Februar 2018

FDK XE8 - 10.2

Hello!

I've already find the time to compile my FDK for XE8 up to 10.2.2!

I finally found the F2018 error so XE8 and Seattle is working again.

So starting at this point I'll prepare the next update.

Mittwoch, 6. Dezember 2017

Delphi Entwickler (m/w) gesucht!

Programmierer (m/w) für Delphi 2007 und XE 10.x.x!


Für die Weiterentwicklung einer Software für Gerichtsvollzieher in Deutschland suchen wir Programmierer mit hervorragenden Delphi Kenntnissen.

Unser Unternehmen ist der Marktführer im Bereich Gerichtsvollziehersoftware und seit über 30 Jahren auf dem Markt. Mehr als 2.200 Gerichtsvollzieher im Bundesgebiet zählen zu den Kunden. Die Software hat einen enormen Funktionsumfang und der Aufgabenbereich der Gerichtsvollzieher ist ausgesprochen groß.


Ihre Aufgaben:

  • Weiterentwicklung einer umfangreichen Software für Gerichtsvollzieher sowie einiger Nebenprodukte
  • Fehleranalyse und Optimierung
  • Unsere Anforderungen:
  • Hervorragende Kenntnisse in Delphi
  • Fähigkeit, sich in mehrere Millionen Zeilen Sourcecode einzuarbeiten
  • Optional: Erfahrung mit FireMonkey zur Entwicklung von Apple sowie Android Apps
  • Hohe Lernbereitschaft, da Sie viele Arbeitsabläufe eines Gerichtsvollziehers und der Justiz nebst zahlreicher Fachbegriffe erlernen müssen
  • Geduld, Freundlichkeit und eigenständiges Arbeiten
  • Gute Ausdrucksweise, einwandfreies Deutsch in Wort und Schrift


Wir bieten:

  • Sehr sicherer Arbeitsplatz und unbefristete Einstellung beim Marktführer
  • Langfristiges Beschäftigungsverhältnis
  • gute Aufstiegsmöglichkeiten.
  • Nur Festanstellung, kein Heimarbeitsplatz, kein Außendienst, gutes Arbeitsgerät – z.B. nutzen die Programmierer bis zu sechs 40“ UHD Bildschirme gleichzeitig.
  • Stetig neue Herausforderungen und Veränderungen
  • 3 im Thema eingearbeitete Programmierer sowie einige Gerichtsvollzieher zur Unterstützung
  • Ggf. Ausweitung Ihrer Tätigkeit (mehr Verantwortung, eigenständige Entwicklung, Schulungen, Präsentationen)
  • Kleines Unternehmen mit momentan 9 Angestellten
  • Ggf. Unterstützung bei einem notwendigen Umzug
  • Über Ihre aussagekräftigen Bewerbungsunterlagen, mit Beschreibung Ihrer Programmiererfahrung/–kenntnisse, Angabe Ihrer Gehaltsvorstellung und Nennung des frühestmöglichen Arbeitsbeginns freuen wir uns.

Für Rückfragen stehen wir gerne zur Verfügung.

Einen kleinen Einblick über unsere Produkte erhalten Sie auf unserer Webseite www.gerichtsvollzieher-software.de.

Baqué & Lauter GmbH
Flamersheimer Weg 3
53881 Euskirchen Palmersheim
fl@gvinfo.de