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
Ɨ