Thunderx Thunderx - 2 months ago 8
HTTP Question

How to Stop all Pipeline tasks correctly

how to stop Pipleline tasks correctly, I've tried but when i press Abort button i get an AV, i'm not too good at debugging,i have reached to

DoOnStop(task);
in OtlParallel then i couldn't figure out what to do next, i believe there is something missing ?

type
procedure SetInProcess(const Value: Boolean);
private
FInProcess: Boolean;
property inProcess: Boolean read FInProcess write SetInProcess;
public
FStopAll: Boolean;
procedure FlushData;
procedure Retriever(const input: TOmniValue; var output: TOmniValue);
...
procedure TForm1.SetInProcess(const Value: Boolean);
var
I: Integer;
begin
if Value = InProcess then exit;
memo1.ReadOnly := Value;
FInProcess := Value;
if Value then
Memo1.Lines.Clear;
Timer1.Enabled := Value;
If not Value then
begin
FlushData;
pipeline := nil;
end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
If not InProcess then exit;
FlushData;
if Pipeline.Output.IsFinalized then
InProcess := False;
end;
procedure TForm1.StartButton(Sender: TObject);
var
i : integer;
urlList : TStrings;
U, S : string;
value : TOmniValue;
begin
urlList := Memo2.Lines;
pipeline := Parallel.Pipeline;

pipeline.Stage(Retriver).NumTasks(StrToInt(Edit12.Text)).Run;

for U in urlList do
pipeline.Input.Add(U);
pipeline.Input.CompleteAdding;
inProcess := True;
end;
procedure TForm1.FlushData;
var v: TOmniValue;
begin
if pipeline = nil then exit;
if pipeline.Output = nil then exit;

Memo1.Lines.BeginUpdate;
try
while pipeline.Output.TryTake(v) do
Memo1.Lines.Add(v.AsString);
if FStopAll then
begin
Pipeline.Cancel;
end;
Memo1.Lines.EndUpdate;
except
on E: Exception do
begin
Memo1.Lines.Add(E.Message);
end;
end;
Memo1.Lines.EndUpdate;
end;

procedure TForm1.Retriver(const input: TOmniValue; var output: TOmniValue);
var
lHTTP : TIdHTTP;
Params : TStrings;
Reply,String1,String2 : string;
begin
X := Input.AsString;
Params := TStringList.Create;
string1 := Extract1(X);
string2 := Extract2(X);;

Params.Add('username=' + string1);
Params.Add('password=' + string2);

lHTTP := TIdHTTP.Create(nil);
try
...
Reply := lHTTP.Post('https://www.instagram.com/accounts/login/ajax/', Params);
if AnsiContainsStr(Reply, 'no')
then
begin
Alive.Add(string1+string2+' Client ok'); ///Alive is Global Var stringlist created earlier
end;
except
on E: EIdHTTPProtocolException do
Exit
end;
lHTTP.Free;
end;
procedure TForm1.AbortButton(Sender: TObject);
begin
try
FStopAll := False;
finally
FStopAll := True;
end;
end;

Answer

In your case of over-simplified one-stage pipeline suffice would be moving check into the worker stage itself.

procedure Retriever(const input: TOmniValue; var output: TOmniValue);
var 
  ....
begin
   if FStopAll then exit;
   X   := Input.AsString;
....

PS. I want to repeat that your code leaks memory badly, and that you ignored all my notes I stated before.

PPS. This code not also makes little sense (there is not point in flip-vloppign the variable to one value then to another) but is syntactically incorrect and would not compile. Thus it is not the same code you actually run. It is some different code.

procedure TForm1.AbortButton(Sender: TObject);
 begin
   try
     FStopAll := False;
   finally
     FStopAll := True;
   end;
 end;