Jump to content

Sonjli

Members
  • Content Count

    13
  • Joined

  • Last visited

Community Reputation

0 Neutral

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Sonjli

    Pipeline multi runnable

    Hi, sorry for late reading. I am trying to build a kind of a "protocol runner". I need an object which can accept different "actions" and then it can be run in loop to repeat the protocol. Example: Name: "Protocol 1: download a file with locks" 1. Wait until "the other" lock file disappear 2. Put "my" lock file in that folder 3. Download the main file 4. process the main file 5. Delete "my" lock file 7. Wait 5 seconds 8. Restart from 1 The entire loop must be run in a separate non-blocking thread. But every loop must be serialized. I thought that pipeline could be the answer, but I can't run it several times in that loop. I may use a state machine (https://github.com/malcolmgroves/TStateMachine) but I need to build several protocols changing one or more "actions" at runtime... I don't know if this is the right choice. Is my idea clear enough? I hope so... 🙂 Thanks
  2. Hi, simple question: how can I run a pipeline more than one time in the same method\procedure\function? I do like this ... MyPipeline := Parallel .Pipeline .stage(myStage1) .stage(myStage2); ... procedure MyProcedure; begin // First run MyPipeline.Run; MyPipeline.input.Add('ONE'); aValue := MyPipeline.Output.Next; // I tries also this... without success MyPipeline.Cancel; MyPipeline.WaitFor(INFINITE); // I do some stuff in the middle // First run MyPipeline.Run; // Here I receive "Pipeline is already running", but I don't think so... :( MyPipeline.input.Add('TWO'); aValue := MyPipeline.Output.Next; ... end; I am not finding any info in the docs. In the sources of IOmniPipeline I see a "opCountStopped" semaphore that is checked "Assigned" in the first run... but I really don't understand why this limits one instance of a IOmniPipeline to be run only one time in the same method. Thanks again Eddy
  3. Sonjli

    Delegation good practice

    Hi Primoz, yes, my example is not so clear. My idea is of making something like a "Guardian\watchdog" (ok, they are not the same...) service who calls an url every X seconds, and if it does not respond then it delegates the calling service to do whatever it wants (it can, for example, stop the running service and restart). I thought the solution was of using the "OnMessage" technique and delegates there the calling service. I don't know if this is the right pattern, nor the right solution, indeed. I hope to be more clear... Thanks
  4. Sonjli

    OnTerminated never triggers

    Hi Primoz, It's all clear. Very clear. This is a new precious info, for me. Where did you get these infos? Only by debugging? ServiceCreate is in one thread, and ServiceStart/ServiceStop in second thread or every event is in a separate thread? (so are they three?) This is the second precious info. Some of my test are closed. This has perfectly sense Thank you very much.
  5. Hi (here again...), I have a doubt about delegation. I have this simple case TWSGuardian = class(...) strict private FOnNotResponding: TProc<Integer>; ... public // Delegation property OnNotResponding: TProc<Integer> read GetOnNotResponding write SetOnNotResponding; end; // OTL task ... Task.Comm.Send(MSG_WSNOTRESPONDING, TOmniValue.CreateNamed(['timeout', LPassedTime])); end; end; end ) .OnMessage(MSG_WSNOTRESPONDING, procedure(const Task: IOmniTaskControl; const msg: TOmniMessage) begin DoNotResponding(msg.MsgData['timeout']); end ); ... procedure TWSGuardian.DoNotResponding(TimeOut: Integer); begin if Assigned(FOnNotResponding) then FOnNotResponding(TimeOut); end; ... When calling the TWSGuardian object I would use a critical section to avoid collisions in case of more than one running TWSGuardian. Like here: begin Grd := TWSGuardian.Create; ... Grd.OnNotResponding := procedure(ATimeOut: Integer) begin if ATimeOut > 1000 then begin // Critical section? RunSomeAlienCode; // How can I be sure this is thread-safe? end; end; ... Grd.Run; ... Grd.Stop; // This safely terminate the task inside TWSGuardian Is this the right way? Is there a common used pattern? How can I move the critical section inside my TWSGuardian instead of using it in the main thread? I am a bit confused. Thanks and sorry for this PITA
  6. Sonjli

    OnTerminated never triggers

    Hi, I attach a mock project with the "OnTerminated" event not firing. - The project is an NTService, so you have to install with "/install" - I write the logs (a bit verbose...) on the default Windows Event Monitor (under Windows\Application) To reproduce - Install - run the service - wait a punch of seconds - Stop the service (not pause, it is not implemented for this purpose) - Open Event Monitor - The messages linked to "OTL.NTService" Origin finish with a serie like this: Keep Alive A try to stop task... FRunner.ExitCode = 0 ServiceStop You'll never find a "Server stopped in ONTERMINATED" message, that is the one fired inside the "OnTerminated" event. I hope to be clear... Thanks again. PS: I use D10.3.1 but I think the sources can be good for oldest versions. OmniThreadNTService.zip
  7. Hello guys, I am working to port a NTService with a WebBroker application (wrapping Daniele Teti's DMVC) from TThread style to OTL. It's almost ok (and amazing, yes!) but in the next code the "OnTerminated" event never triggers (I never see the "Server stopped" string in the log)... What am I wrong? Thank you in advance ... LServer := TIdHTTPWebBrokerBridge.Create(nil); FRunner := CreateTask( procedure(const Task: IOmniTask) var LMvc: TIdHTTPWebBrokerBridge; i: Integer; begin LMvc := Task.Param.ByName('mvc'); RunServer(8889, LMvc); try repeat Sleep(25); {$IFDEF DEBUG} inc(i); if (i mod 40) = 0 then Task.Comm.Send(MSG_LOG, 'Keep Alive'); {$ENDIF} until Task.Terminated; finally StopServer(LMvc); end; end ) .SetParameter('mvc', LServer) .OnMessage( procedure(const Task: IOmniTaskControl; const msg: TOmniMessage) begin if msg.MsgID = MSG_LOG then begin Log.Debug(msg.MsgData, ''); // LogMessage(msg.MsgData, EVENTLOG_INFORMATION_TYPE); end; end ) .OnTerminated( procedure(const Task: IOmniTaskControl) begin Task.Comm.Send(MSG_LOG, 'Server stopped'); if Assigned(Task.FatalException) then begin var ELocal := Task.DetachException; Task.Comm.Send(MSG_LOG, Format('...with Errors: "%s"', [ELocal.Message])); end; end ); ... // In the ServiceStart event ... FRunner.Run; ... // In the ServiceStop event ... FRunner.Terminate; ...
  8. Sonjli

    10.3.1 Rio (26.0.332194899) crash

    Thank you. Your tool is a must for my team. I try asap! EDIT: I tried and it works like a charm. Thanks again. PS: Is it in your plan to add default D10.3 themes?
  9. Hi, as in title, I have this crash with all the downloadable and compatible versions in http://mmx-delphi.de I have the same report as here:
  10. Sonjli

    Newbie: memory management

    OK, but THAT is the problem... if I create the group outside the loop then memory increase; if I put that inside the loop, memory is stable. Anyway, I am trying with background workers. They are awesome.
  11. Sonjli

    Newbie: memory management

    Thanks Olivier. I'll try the background workers. For the sentence: Sorry, but I didn't understand... (maybe my poor english? 🙂 )
  12. Sonjli

    Newbie: memory management

    While experimenting I found that the problem is the creation of the otlWaitGroup. I created it out of the main loop; so now I moved it inside the loop like in the code below. I have some doubts: Why the reference to OmniTasks stay inside the WaitGroup until it is detroyed? Are they weak references? Why do I have to create many waitGroups instead of creating only one, and use it many times? Thanks anyone. while not GetArticoloVersato.getTabella.Eof do begin ... ATaskList := CreateTaskControlList; otlWaitGroup := CreateTaskGroup; // Here create it try // Run all registered threads FBroadcastActions.ForEach(Action<IBroadcastAction>( procedure(ABroadcastAction: IBroadcastAction) begin  ATaskList.Add(CreateTask( procedure(const Task: IOmniTask)  begin Sleep(100); // Only for test // ABroadcastAction.Run(Task, GetMacchina); end).MonitorWith(FEventMonitor).Join(otlWaitGroup).Schedule(otlPool)); end )); otlWaitGroup.WaitForAll; if otlPool.CountExecuting > 0 then raise Exception.Create('Oh my..., thread still running'); ATaskList.Clear; finally otlWaitGroup := nil; // Here free it ATaskList := nil; end; ... end;
  13. Hi, I am trying to use your fantastic library (thanks for it). I have a doubt about freeing memory. I have a master thread (a standard TThread by Delphi) that is responsible to run some omni tasks. I use to do it in this way: procedure TThreadMonitorBroadcast.Execute; begin ... while not GetArticoloVersato.getTabella.Eof do begin ... ATaskList := CreateTaskControlList; try // Run all registered threads FBroadcastActions.ForEach(Action<IBroadcastAction>( procedure(ABroadcastAction: IBroadcastAction) begin ATaskList.Add(CreateTask( procedure(const Task: IOmniTask) begin Sleep(100); // Only for test // ABroadcastAction.Run(Task, GetMacchina); end).MonitorWith(FEventMonitor).Join(otlWaitGroup).Schedule(otlPool)); end )); otlWaitGroup.WaitForAll; if otlPool.CountExecuting > 0 then raise Exception.Create('Oh my..., thread still running'); ATaskList.Clear; finally ATaskList := nil; end; ... end; ... end; It looks like everything works finem but RAM is increasing at every loop. What am I wrong? I tried to use a TaskControlList, but without success.... Thanks in advance Eddy
×