Jump to content

Sonjli

Members
  • Content Count

    94
  • Joined

  • Last visited

Posts posted by Sonjli


  1. Ok, this is my last chance... after this you must wait for @Primož Gabrijelčič

     

    Try something like this:

    procedure ProcessMessages;
       var
         Msg: TMsg;
       begin
         while integer(PeekMessage(Msg, 0, 0, 0, PM_REMOVE)) <> 0 do begin
           TranslateMessage(Msg);
           DispatchMessage(Msg);
         end;
       end;
    
    ...
    	FKeepAlive.Stop;
        repeat
        	ProcessMessages;
        until FKeepAlive.Terminate(1000);
    ...

     


  2. The only problem I know about console apps is about "omni messaging system". Look at documentation http://www.omnithreadlibrary.com/book/chap05.html#introotl-messagelooprequired-console

     

    Maybe after 5 seconds the parallel timer is not terminated.

    Try this:

    destructor TjBASEComm.Destroy;
    begin
      if Assigned(FKeepAlive) then
        try
          FKeepAlive.Stop;
          FKeepAlive.Terminate;
          FKeepAlive.WaitFor; // This wait until the task is REALLY terminated. If it is stuck then the problem is elsewhere
        except
        end;
    
      try
        FConn.Free;
      except
      end;
    
      inherited;
    end;

    There is also a doubt about "FConn.SendStr('')": what does it do?

     

    Regards,

    Eddy


  3. Hello,

    I am trying to read from a tcp socket some data and elaborate it in a pipeline.

    The pipeline should do something like this:

    Stage 1: polling the tcp socket and write the list of bytes in Output

    Stage 2: read output and make some calculation with bytes (I need to know when a packet starts and ends)

    The problem is that in the second stage I receive a list of simple "numbers" (a list of bytes) not continously. I mean that the bytes arrive in groups, but I need to save them in a global array to make my decisions.

    Questions:

    1. Is the pipeline the right choice?

    2. How can I use a global array inside a Pipeline? (I can't use SetParameter as in ITaskController)

     

    Thanks in advance

    Eddy


  4. Ok, thank you as usual.

    So, I have this strange behavoiur:

    The task receiving messages sometimes slow very down, and I can see 30/40 messages queued from the "external" thread, but only one elaboration of my task loop.

    So in this situation the queue risks to be full very quickly (1000 messages I read in docs).

    But I don't know why this happens... a loop too thight?


  5. Hello,

    I am trying to start communication between two threads.

    The first thread is not mine, it come from an external component library (always Delphi).

    This component has an event "OnSomethingHappens" that fires in a separate thread.

    So, in this event I use the OTL Communication system. For example: lMyTask.Comm.Send(WM_MYMESSAGE, MyObject);

    In my task I do a simple loop like this:

     

                      while Task.Comm.Receive(lMsg) do
                      begin
                         if lMsg.MsgID = WM_MYMESSAGE then
                           etc.

     

    But watching at OTL demos I see that you do somthing like this:

     

      repeat
        case DSiWaitForTwoObjects(task.TerminateEvent, task.Comm.NewMessageEvent, false, task.Param['Delay']) of
          WAIT_OBJECT_1:
            begin
              while task.Comm.Receive(msgID, msgData) do begin
                if msgID = MSG_CHANGE_MESSAGE then
                  msg := msgData;
              end;
            end;
          WAIT_TIMEOUT:
            task.Comm.Send(0, msg);
          else
            break; //repeat
        end;
      until false;

     

    Sorry for my ignorance but I don't understand why you use the DSiWaitForTwoObjects and what it means.

    As I am having some problems in my loop, I think they are related to this use case... so can you explain, please?

     

    Thanks again,

    Eddy

     


  6. 6 minutes ago, Primož Gabrijelčič said:

    If you run your program in debugger, it should pop up when the exception occurs - unless you have that exception type listed on the 'ignored exception' list.

     

    Alternatively, open OtlTaskControl unit and search for TOmniTask.InternalExecute. Inside you'll find:

    
            try
              if otSharedInfo_ref.ProcessorGroup >= 0 then
                otExecutor_ref.SetProcessorGroup(otSharedInfo_ref.ProcessorGroup);
              if otSharedInfo_ref.NUMANode >= 0 then
                otExecutor_ref.SetNUMANode(otSharedInfo_ref.NUMANode);
              otExecutor_ref.Asy_Execute(Self);
            except
              on E: Exception do begin
                taskException := Exception(AcquireExceptionObject);
                FilterException(taskException);
                if assigned(taskException) then
                  SetException(taskException);
              end;
            end;

    This is the main exception handler for a task. You can log information inside the exception handler or put a breakpoint there.

    Thank you very much for the fast response.

    Naturally, this bug don't comes with debugging but in real production from customer...

    I'll try the logging solution. Thanks again.

     

    ps: any idea for the OnTerminated event in the child task?


  7. Hello,

    I have a task which dies unexpectedly and I don't know how to check this situation.

    I know for sure it is something related with my software. I added all the "try\except" needed to catch the exception but the task dies the same.

    The task (I will call it "Child") is created by a MainTask, but when the child dies, the father continues without problems.

    The Main Task creates a lot of this Child. Every child is good isolated. There are not concurrent resources used between them.

    The child task contains an infinite loop testing the task.terminated.

    The child task is added to a TaskGroup and I tested that when it "dies bad" also disappear from TaskGroup.

    The "OnTerminated" on child does not trigger in this scenario. The child thread never call the OnTerminated, neither in "good termination" case. I don't know why.

    I don't know how to catch the "FatalException" of the child.

    How can I test this?

    I don't know how many other infos you need.

     

    Thanks,

    Eddy


  8. 4 hours ago, Stefan Glienke said:

    Only testing the code yourself will show but I can smell a potential memory leak due to circular references caused by anonymous methods and capturing of the IOmniTask within itself - nested anonymous methods can be a bit nasty sometimes.

    Yes, in my tests I found some strange behaviours within the omnitask and reference counting, very hard to explain and to test.

    But after days of pain I found the problem, and I am pretty sure it is not related to Omni or Spring. I am writing a microservices framework with mqtt using a library with some problems with threading...

    Thanks and keep up the good job

    Eddy


  9. Hello,

    I will always repeat that without mmx my team could be 5 times slower... thanks for this diamond 🙂

    I only have a small glitch: when I drag a generic Interface (i.e.: IMyInterface<TDummyType>) over a concrete class that I want to implement that generic Interface, then mmx don't work. It  says that it can't parse the class.

    Can this be solved?

    Thanks again,

    Eddy


  10. Hi,

    I have a small task where I use this technique:

          CreateTask(
             procedure(const Task: IOmniTask)
    		var
               lPlugObject: IPluggable;
            begin
    ...
                   lPlugObject := FPlugProtocolFactory(lTaskPlugAndParams);
                   // Can I use this?
                   lPlugObject.Stoppable := function: Boolean
                      begin
                         result := Task.Terminated or Task.CancellationToken.IsSignalled;
                      end;
                   
                   lPlugObject.Connect;
                   lPlugObject.Run;
    ...
    		end)
    ...

    The PlugObject has an infinite loop inside the Run method, and sometimes it checks the mothod "Stoppable".

    PlugObject is a plain object without threads or task, only a "repeat until false" loop.

    I need to know if this use of anonymous can create problems with the threading concurrency in some way.

    Thanks,

    Eddy


  11. 3 hours ago, Uwe Raabe said:

    You can also check the dproj file the DesignClass and FormType values to be correct.

     

    
            <DCCReference Include="Unit527.pas">
                <Form>DataModule527</Form>
                <FormType>dfm</FormType>
                <DesignClass>TDataModule</DesignClass>
            </DCCReference>

     

    Ciao Uwe,

    I try asap... never touched the dproj :B

    thanks


  12. 7 hours ago, Kas Ob. said:

    Why not to start debug your application the right way ?

     

    If you don't have a file logger, then simply use OutputDebugString in all of you units, use it directly or with wrapper method, you also can add a directive to enable it when you need for later usage.

    Use OutputDebugString in initialization and finalization in every unit ( you can also add it in the dpr file itself) , download DebugView from here https://docs.microsoft.com/en-us/sysinternals/downloads/debugview

    The output messages will be captured in DebugView when your application outside the IDE debugger, while the Debugger messages ( Events windows) will capture the text, save both outsputs to text files, compare and you will find what is going wrong.

     

    Such process will take 5 minutes of your time and will give you 100% accurate picture what had been changed, no matter how complicated your application is.

    Sorry @Kas Ob. but my problem is at designtime, not runtime. The problem happens in IDE.

    thanks.


  13. My dpr is not exactly canonical... so, is there any problem with IDE ancestor resolution and "strange" disposition of dpr code?

    For example I have a wrapper object for "Application", so there is no standard

    Application.createForm();

    Application.Initialize;

    Application.Run;

     

    Can this be a problem?

    I didn't try to make a cosole app (my apps are similar to console applications) with my datamodules, in fact... I can try


  14. Everything is exactly as you write. Every datamodule is correctly declared in dpr with path and comment.

     

    Real code:

      ...
      UInterfacedDataModule in '..\..\..\Model\UInterfacedDataModule.pas' {DMInterfacedDatamodule: TDataModule},
      UDMCustomModel in '..\..\..\UDMCustomModel.pas' {DMCustomModel: TDataModule},
      UDMUniModel in '..\..\..\Model\UniModel\UDMUniModel.pas' {DMUniModel: TDataModule},
      ...

     


  15. Hi all,

    I perfectly know the error in subject. It is due of an ancestor form\datamodule missing in the project (don't go deep in all other sub-cases this error can happen...).

    In my dpr I have all of the ancestors, and if I open them in IDE in the correct order (grandfather - father - child) everything is fine. BUT if I open only a "child" then this error happens.

    My project is a bit complicated (I make use of injection, threads, etc.) but this simple error is making me and my team crazy.

     

    Any idea how to solve this situation?

     

    The object tree is something like:

    TBaseDatamodule

    |- TChildDatamodule

    |-- TConcreteDatamodule

     

    Thanks in advance,

    Eddy


  16. 4 hours ago, David Heffernan said:

    Why don't you use the system scheduler? 

    Because I need to be in strict control with the scheduling and I am in cross development (Linux and Windows at least).

    1 hour ago, Fr0sT.Brutal said:

    I've no experience with OTL but a primitive solution comes to mind - launch a task with wait

    ev := CreateEvent(...)

    if WaitForSingleObject (ev, ScheduledTime-CurrentTime) = WAIT_TIMEOUT then

    ... do something scheduled

     

    to be able to cancel the wait, additional waitable object will be required and WaitForMultipleObjects instead

    Interesting... any example? I know I can do something like this in OTL, so a "standard" example could help me to figure out.

×