Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Parallel Programming Library / 5 сообщений из 5, страница 1 из 1
22.04.2021, 22:06
    #40064934
bzums
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Parallel Programming Library
Есть работающее решение - некий сервис , который посредством REST обслуживает базу (в основном, добавление и удаление данных).
В настоящий момент это просто отдельная процедура (для каждой операции), которая вызывается извне.

Надо сделать так, чтобы можно было ее еще стартовать много раз, отменять и так далее, плюс ко всему учитывать, что одна и таже процедура может работать на несколько баз.

Parallel Programming Library как раз вроде решает проблему.
Если говорить про TTask, то все нормально:
1) добавив глобольный Stringlist просто заношу туда список баз по которым идет работа, отработала - удаляю. На основании этого второй раз удаление уже не запустить.
2) Таск можно поставить в очередь - пока не отработает предыдущий этот не запусится. Отсюда вылезла проблема - TTask.WaitForAll(tasks) работает странно - как уже сказал прекрасно организует очередь, но REST информирует неверно. Если например, не использовать TTask.WaitForAll(tasks), то таск долгий выполняется как бы в потоке, но ресту идет ответ, что выполнено (и наоброот - когда указана TTask.WaitForAll(tasks)), то второй так и ждет, пока текущий не закончится и REST естественно получает правдивую информацию.

Самое главное, на что обратил внимание, assigned(proc) не работает для всех процессов , видимо объект созлается свои всегда. Поэтому и пришлось городить с стринг листом.

Не покидает чувство ,что это немного не то, что хотелось бы.


Не могу понять как сюда прицепить TMonitor (советуют упорно) - посмотрел, так он просто блокирует объект и при освобождении уведомляет и наоборот.
Потоки тоже какбы не то, тяжеловато мне с ними.

Главное условие, что надо процедура (типа процессы) запускать независимо, но брать в учет, что таск по той же базе можно:
1) запустить, если не работает другой
2) елси работает - то предыдущий прервать
3) каким то образом получить статус - выполняется ли и если да, то какое состояние (идентификатор ?)

Вопрос в том, что можно тут придумать (мое решение не кажется жизнеспособным).
Большое спасибо.
...
Рейтинг: 0 / 0
23.04.2021, 08:17
    #40065021
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Parallel Programming Library
Много букв без кода.
А как твои таски обращаются к StringList, потокобезопасно?
А как твои таски пишут в БД, потокобезопасно?

TMonitor (советуют упорно) для чего?
...
Рейтинг: 0 / 0
23.04.2021, 09:58
    #40065059
vkorshun
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Parallel Programming Library
Мне кажется в Вашем случае надо использовать события а не ждать когда закончатся все задачи. Как вариант task шлет событие что он закончился или использовать Future. Но правильно ли что Rest что то ждет ? Получив запрос сервер должен забросить ее в очередь на выполнение и ответить что задача принята (вернуть какой то ID) а дальше клиент должен опрашивать состояние его задачи. А когда она выполнится (результат выполнения можно записать в базу) - клиент получит уведомление при очередном запросе состояния и перестанет опрашивать. Для очереди лучше использовать blockingqueue . Если не использовать асинхронность то клиент может отвалится по таймауту в случае тяжелой задачи. Насчет глобального stringlist - надо писать либо свой потокобезопасный либо готовые есть например в OmniThreadLibrary (может и в Parallel). Возможно лучше в момент загрузки прочитать список нужных коннектов из настроек и создать необходимое количество пулов коннектов и наверно по URL запроса Вы определяете какой пул надо использовать
...
Рейтинг: 0 / 0
23.04.2021, 14:02
    #40065200
bzums
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Parallel Programming Library
cptngrb
Много букв без кода

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
unit myservice;

interface

uses ...

var
    global: TStringList;

type
[ServiceImplementation]
TRunSQL = class (TInterfacedObject, IRunSQL)
   public
      function Run1( param integer ): string;
   private
      proc: ITask;
end;

implementation

uses ...

function TRunSQL.Run1( param: integer ): string;
begin
  TMonitor.Enter(global);
  begin
    try
      if global.IndexOf('dbname') >= 0 then begin
        //on jo olemassa
        Result := 'Prosess is already running.';
        exit;
      end else begin
        global.Add ('dbname');
      end;
    finally
      TMonitor.Exit( global) ;
    end;
  end;
  proc := TTask.Create(
//////////////////////////
    procedure()
	......
	//тут тело, много кода, но помимо всего прочего есть
	query.sql.text := 'drop database dbname'; 
        query.run;
	......
      TMonitor.Enter(global);
      begin
        try
          for i := global.Count - 1 downto 0 do begin
          if global[i] = 'dbname' then
            global.Delete(i);
          end;
        finally
          TMonitor.Exit( global) ;
        end;
      end;
//////////////////////////
    end


   );
  proc.Start;
  TTask.WaitForAll(proc);
  proc := nil;
  Result := 'Task is finished.';

end;

procedure TRunSQL.Create( Sender: TObject );
begin
  global := TStringList.Create;
end;

procedure TRunSQL.Destroy( Sender: TObject );
begin
  global.Free;
end;
...
Рейтинг: 0 / 0
26.04.2021, 12:49
    #40065917
bzums
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Parallel Programming Library
Выяснидпсб одна неприятная (непонятная) особенность - если не использовать WaitForAll, то особенно долгий таск создается (что-то делает, наверное убивается), но класс из которого он был создан (давным давно умер).
Причем нет потенциальной разницы между
Код: sql
1.
2.
3.
4.
  proc.Start;
  proc := nil;
  form.close;
end;

и
Код: pascal
1.
2.
3.
  proc.Start;
  form.close;
end;


Потенциально MemoryLeaks, не ?


Задумка была как раз сделать возможность запускать некие процессы независимо.
Таски позволяют просто распаралелить....

Получается, потоки единственное решение?
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Parallel Programming Library / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]