Jump to content

Lars Fosdal

Administrators
  • Content Count

    3524
  • Joined

  • Last visited

  • Days Won

    116

Posts posted by Lars Fosdal


  1. We do something similar to what Stefan does.

     

    We have a number of services, all implemented around a server core class which in itself is unaware of if it is running as a service or as an application.

    We wrap TService using a small "helper" class to set up the appropriate server core descendant and hook the svc events that we care about.

    The test application simply instantiates the same core object and hooks in a few handlers that f.x. will show certain config info and log outputs in a list view.

     

    Using that approach, writing and testing service code has pretty much become trivial.

     

    We did run into one snag the other day, when we moved a file share URL from a server drive share to a DFS share.  Turns out that Local System accounts cannot access DFS file shares, so you either have to give the machine access to the DFS through AD, or run the service under an AD user account that can be given access. We chose the latter.


  2. I use a queue,  Each thread writes log data to the queue which basically is a ring buffer. The log thread periodically (every two seconds) flush the data asynchronously from the ring buffer, writing multiple entries at a time.

    I really don't like relying on messages for inter-thread communication - with one exception: the background threads notifying the foreground thread that there is data to fetch from the thread out-queues.


  3. https://quality.embarcadero.com/browse/RSP-23056

     

    Debugger watch / evaluate shows wrong values for inline declared local variables with duplicate names within same routine.

    Put a breakpoint on each of the lines with breakpoint in the comment.
    Run
    at A, hover over variable s, or evaluate s shows value A
    at C, hover over variable s, or evaluate s shows value A - should have been C
    The actual value is C - so it is a debugger bug

    program ReusedLocalVariables;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      System.SysUtils;
    
    type
      TTest = class
      public
        procedure Check(const aValue: String);
        procedure Test;
      end;
    
    procedure TTest.Check(const aValue: String);
    begin
      Writeln(aValue);
    end;
    
    procedure TTest.Test;
    begin
      begin
        var s := 'A';
        Check(s);   // Breakpoint: S shows 'A' - Output in check = 'A'
      end;
      begin
        var s := 'C';
        Check(s);   // Breakpoint: S shows 'A' - should have been 'C' - Output in check = 'C'
      end;
    end;
    
    begin
      try
        var Test := TTest.Create;
        try
          Test.Test;
          Test.Free;
        except
          on E: Exception do
            Writeln(E.ClassName, ': ', E.Message);
        end;
      finally
        Write('Press Enter: ');
        Readln;
      end;
    end.

     

    • Like 1
    • Sad 1

  4. 18 hours ago, Fr0sT.Brutal said:

    Thanks to all who answered, sorry for late response.

    Docs are good but hardly ever being read from A to Z. Interface should be intuitive IMHO or at least give some hints.

    Very interesting regarding work queues. Have you got any shareable code to look at?

     

    What about Synchronize/Queue? I always tried to avoid it but see Emba have done pretty much in this area. Is it safe?

    Sorry, no code to share as it is embedded in a larger framework.
    I do use the queues in Omni Thread Library from @Primož Gabrijelčič down in the core, though.

    As for Synchronize: Just say no.

    • Thanks 1

  5. VCL.Forms, VCL.Printers and VCL.StdCtrls has a few of these, but for only for function parameters in CLR code.

    {$IF DEFINED(CLR)}
    type
      TMonitorEnumerator = class
        FList: TList;
        FEnumProc: TMonitorEnumProc; // reference to the delegate so the garbage collector doesnt free it
        constructor Create(List: TLIst);
        function EnumMonitorsProc(hm: HMONITOR; dc: HDC;
          [in] var r: TRect; Data: LPARAM): Boolean;
      end;
    {$ENDIF}

    and on the topic of CLR: https://stackoverflow.com/questions/2210122/why-are-there-so-many-if-definedclr-in-the-vcl-rtl

    Yeah... that stuff really should be made to go away. 

     

    • Like 1

  6. 10.4 has "language improvements".


    Some of the stuff I'd want to see here - although I expect only the two top ones to actually be candidates...

     

    - parameterless record constructors

    - nullable types

    - proper record constants that are treated as constants

    - generic support for nullable types

    - generic constraint for enumerated types so that you can for a Value:T use Ord(Value), Set of T, Value in Set, etc.

    - generic constraint for number, so that you can use mathematical operators on a value of T

    - generic record helpers - TArray<T> / record helper for TArray<T>

    - helper aggregation/overload/scoping so that one helper does not have to replace another

    - lambda expressions

    - ternary operator to shorten those lambdas

    • Like 2

  7. I prefer using thread safe queues  aka the mailslot principle.

    Normally I let my worker threads have an workqueue and a reference to the mainthread responsequeue.

    I post a task to the workqueue, getting a task ticket, and the background thread posts a response/result  package to the responsequeue, marked with that task ticket.

    I can either poll the response queue with the ticket, or I can have the thread fire off a windows message to the main thread that basically says "check the queue for this task ticket"

    Benefits: 100% async and isolated.  No concurrent access to data.  All updates can happen at the leisure of the main thread.

     


  8. On 8/4/2019 at 1:23 PM, Michel Bernabela said:

    >    FiApp_PushPunchCommand.Parameters[0].Value.AsDateTime := FPdtFrom;
    >    FiApp_PushPunchCommand.Parameters[1].Value.AsDateTime := FPdtDateIn;
    >    FiApp_PushPunchCommand.Parameters[10].Value.SetStream(FPmsPic, FInstanceOwner);

    Is there a particular reason that the params are numbered 0, 1, 10 ?

     

    On the server side - have you inspected the stream after you fill it from the request?  Does the length of the stream match the size of the image?


  9. If you installed 10.3.1 in your VM with the webinstaller, you can simply download the new webinstaller for 10.3.2 and run it.  It will still automatically uninstall the previous version, but if you select to keep the configuration, it will remain configured for 10.3.2.

    If you installed 10.3.1 in your VM from the ISO image, I recommend uninstalling it before installing the 10.3.2 from either the new ISO image or the new webinstaller.

     

    Personally, I always use the webinstaller.

     

    /off-topic:

    Considering the number of new features in 10.3.2, I am a little miffed that you can't have both 10.3.1 and 10.3.2 installed at the same time.

    • Like 1
×