Jump to content
Sonjli

Delegation good practice

Recommended Posts

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

 

 

 

Share this post


Link to post

I don't really understand your questions, sorry.

 

If you run some external code, you cannot be sure if it is thread-safe. You should protect access to it with some synchronization mechanism. 

 

A whole idea of a guardian object with a "not responding" callback is new to me. I don't believe it is a commonly used pattern. I can't comment on it as I never used it in practice.

Share this post


Link to post

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

Share this post


Link to post

Yes, OnMessageis designed for this.

 

OTL takes care that OnMessage handler is executed in the thread which created the background task (in the owner).

Edited by Primož Gabrijelčič
typo
  • Thanks 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×