Recent

Author Topic: Should I .Create/.Free HTTPSend in a loop ?  (Read 2467 times)

RedOctober

  • Sr. Member
  • ****
  • Posts: 452
Should I .Create/.Free HTTPSend in a loop ?
« on: February 21, 2018, 06:01:25 am »
Platform:  Lazarus 1.8.1, FPC 3.0.5, Synapse 40

I have to check about 5 URLs, repeatedly every 15 seconds.   I found that the only way I can get HTTPSend to work, is to create it and destroy it every loop iteration.  Like this:

Code: Pascal  [Select][+][-]
  1.  
  2.  
  3.   HTTPSender := nil;
  4.   try
  5.     for i := 0 to Pred(url_lst.Count) do
  6.       begin
  7. ...
  8.         HTTPSender := THTTPSend.Create;
  9.         HTTPSender.Timeout := ded_url_to * 1000;
  10.         HTTPGetResult := HTTPSender.HTTPMethod('GET', URL);
  11.  
  12.         if HTTPGetResult then
  13.           begin
  14. ...      
  15.           end
  16.         else
  17.           begin
  18. ...              
  19.           end;
  20.  
  21. ...
  22.         if Assigned(HTTPSender) then
  23.           begin
  24.             HTTPSender.Free;
  25.                         HTTPSender := nil;
  26.           end;
  27.  
  28.  
  29.         Application.ProcessMessages;
  30.       end;
  31.  
  32.   finally
  33.     if Assigned(HTTPSender) then
  34.       HTTPSender.Free;
  35.   end;
  36.  


Is this a reasonable approach?  Is there a better one?  All this creating and .Freeing seems wastful of CPU resourses.  However, I cannot get a HTTPSend(er) to connect to any subsequent URLs once it is created.


taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Should I .Create/.Free HTTPSend in a loop ?
« Reply #1 on: February 21, 2018, 06:08:20 am »
http://synapse.ararat.cz/doc/help/httpsend.THTTPSend.html#Clear
Code: Pascal  [Select][+][-]
  1.  
  2.   HTTPSender := THTTPSend.Create;
  3.   try
  4.     HTTPSender.Timeout := ded_url_to * 1000;
  5.     for i := 0 to Pred(url_lst.Count) do
  6.       begin
  7. ...
  8.         HTTPGetResult := HTTPSender.HTTPMethod('GET', URL);
  9.  
  10.         if HTTPGetResult then
  11.           begin
  12. ...      
  13.           end
  14.         else
  15.           begin
  16. ...              
  17.           end;
  18.  
  19. ...
  20.         HTTPSender.Clear;
  21.         Application.ProcessMessages;////<----------- danger! Danger Will Robinson. Danger!
  22.       end;
  23.  
  24.   finally
  25.       HTTPSender.Free;
  26.   end;
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

RedOctober

  • Sr. Member
  • ****
  • Posts: 452
Re: Should I .Create/.Free HTTPSend in a loop ?
« Reply #2 on: February 21, 2018, 06:32:59 am »
Thank you taazz it works!  What is the danger of putting an Applicagtion.ProcessMessages inside my loop?  I'd like to update my UI so the user knows what is happening.  Is there a different way to update the UI without wrecking something in the HTTPSender's "world" ?

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Should I .Create/.Free HTTPSend in a loop ?
« Reply #3 on: February 21, 2018, 06:52:40 am »
think of a lazarus application like this.

Code: Pascal  [Select][+][-]
  1. repeat
  2.   processMessages;
  3.   RunSynchronise;
  4.   RunQueuedMethods;
  5.   RaiseIdleEvent;
  6. until ApplicationEnd
  7.  
  8. Procedure ProcessMessages;
  9. begin
  10.   GetMessage;
  11.   HandleMessage; <-- in here you call processMessages again.
  12. end;
  13.  
So depending on the code you will have re entrance problems, enabled buttons when you shouldn't be able to press them and other out of sync processes which are hard to impossible to predict or debug. In delphi there is the repaint method that only retrieved and processed the painting messages (invalidate, paint, print etc) ignoring everything else, that allowed you to minimize re entrance problems.
As far as I know that does not work in lcl. You should try to use one of the parallel libraries pasMP (search github.com) and I forget the other one sorry, but its in CCR repo that will help you to run methods/procedures in parallel with out writing a tthread descendant.
« Last Edit: February 21, 2018, 06:56:06 am by taazz »
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

rvk

  • Hero Member
  • *****
  • Posts: 6111
Re: Should I .Create/.Free HTTPSend in a loop ?
« Reply #4 on: February 21, 2018, 10:18:00 am »
You should try to use one of the parallel libraries pasMP (search github.com) and I forget the other one sorry, but its in CCR repo that will help you to run methods/procedures in parallel with out writing a tthread descendant.
Probably MTProcs. See wiki: http://wiki.freepascal.org/Parallel_procedures

Although I found in the other topic that this library (MTProcs) is far from ideal. You need to split your work into equal multiple threads yourself. You'll need to divide i.e. 100 runs over 8 threads yourself (so 13 runs per thread) and if one (or more) thread(s) ends the run early it sits there doing nothing. I've created a small example parallel_thread in that post which does it the same way as TParallel.&For() in Delphi, taking each run separate and assign it to a available workerthread. That example is also much smaller and easier to understand. Maybe it's not as sophisticated as pasMP (it still needs some work) but it does the job it needs to do.

Not sure if pasMP can really run all runs parallel without needing to divide the work beforehand.

RedOctober

  • Sr. Member
  • ****
  • Posts: 452
Re: Should I .Create/.Free HTTPSend in a loop ?
« Reply #5 on: February 21, 2018, 08:35:14 pm »
Sounds like a lot of coding hassle. Thanks taazz and rvk.  I think I will just let my UI be a little klunky during HTTPSend events (due to keeping everything in the single main thread).  If it makes for a more reliable app, that's fine.  My app is meant to be run in the background anyway, not interacted with very often.

 

TinyPortal © 2005-2018