Sprawdzenie, czy zadanie jest już wykonywane - WebApi

Sprawdzenie, czy zadanie jest już wykonywane - WebApi
JU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5046
0

Hej, mam taki problem, który wydaje się ciekawy i można go ugryźć na kilka sposobów.

Jest sobie bardzo proste ASYNCHRONICZNE WebApi. Zadaniem tego API jest po prostu odpalenie długotrwałej operacji po otrzymaniu requestu. Ta operacja może trwać nawet kilka godzin.

I jest ograniczenie, że można uruchomić tylko jedną operację jednocześnie. Tzn. aby odpalić następną, najpierw ta działająca musi się zakończyć.

I pytanie, jak sprawdzić, czy ona jeszcze trwa?

Sposób 1
Zapisać stan w bazie danych. Na końcu operacji zmienić stan na finished, a potem sprawdzić, czy jest finished, czy nie.
Problem
A co jeśli z jakiegoś powodu apka się wyrżnie i zostanie zrestartowana? Stan tamtej operacji cały czas będzie ustawiony na "running" i nie będzie można odpalić kolejnej bez grzebania w bazie danych

Sposób 2
Zarejestrować sobie jakiegoś singletona, do którego będę przekazywał uruchomiony obiekt Task. Potem sprawdzam, czy ten singletonowy serwis ma Task, który chodzi. Co daje nawet możliwość przerwania go.
Problem
Coś mi tu śmierdzi, ale nie wiem co. Może niezgodność z RESTApi? Ale przecież to jest zgodne z asynchronicznymi api.

Sposób 3
Dokładnie tak samo jak 2, tylko użyć HostedService.
Problem
???

A jak Wy byście podeszli do tematu? Jakieś plusy i minusy konkretnych rozwiązań? A może inne możliwości?

AD
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 342
0

A to nie takie coś https://learn.microsoft.com/pl-pl/dotnet/csharp/language-reference/statements/lock
Jak potrzebujesz informować użytkownika o tym że cos chodzi to flaga w bazie plus jakiś status zrzucany do bazy. Brak statusu w odpowiednim czasie oznacza że coś się wysypalo i należy ustawić odpowiednio flagi.

AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
0

A co jeśli z jakiegoś powodu apka się wyrżnie i zostanie zrestartowana? Stan tamtej operacji cały czas będzie ustawiony na "running" i nie będzie można odpalić kolejnej bez grzebania w bazie danych

How do I register code to run when shutting down an ASP.NET web application using the new .NET 6 format?

Co do problemu ze sposobu 1. Można wychwycić zamykanie się API i zmienić stan trwającej operacji.

SA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1452
0

To nie jest zadanie rekrutacyjne? Robiłem takie dla jednej firmy :D

M0
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 373
0

A co jeśli z jakiegoś powodu apka się wyrżnie i zostanie zrestartowana? Stan tamtej operacji cały czas będzie ustawiony na "running" i nie będzie można odpalić kolejnej bez grzebania w bazie danych

Sprawdzaj na starcie apki czy w bazie są operacja o statusie running, jak tak to ponów, jak nie to bierz kolejną.

Sposób 2 - głupi

Osobiście wykorzystał bym hangfire, tam na pewno da się ustawić, aby wykonywał tylko jedną operację na raz. Dzięki temu nie przejmujesz się niczym, jak apka się wywali, to hangfire sam wznowi nieudane operacje.

Damian Korczowski
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 111
0

HangFire domyslne mia workery które mogą brać zadania w kolejce więc jak ustawi sie 1 workera to będzie brał jedno zadanie na raz.

No i polecam HangFire bo kiedyś pisałem jakieś background services itp. ale nie ma co na nowo odkrywać koła.

bakunet
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 1683
0
Juhas napisał(a):

Sposób 1
Zapisać stan w bazie danych. Na końcu operacji zmienić stan na finished, a potem sprawdzić, czy jest finished, czy nie.
Problem
A co jeśli z jakiegoś powodu apka się wyrżnie i zostanie zrestartowana? Stan tamtej operacji cały czas będzie ustawiony na "running" i nie będzie można odpalić kolejnej bez grzebania w bazie danych

Jeśli apka się wyrżnie i zrestartuje, to przy inicjalizacji możesz na start resetować wszystkie stany w bazie na domyślne dla niezaczętego, jeśli takie rozwiązanie zrobi Ci robotę.

Juhas napisał(a):

Sposób 2
Zarejestrować sobie jakiegoś singletona, do którego będę przekazywał uruchomiony obiekt Task. Potem sprawdzam, czy ten singletonowy serwis ma Task, który chodzi. Co daje nawet możliwość przerwania go.
Problem
Coś mi tu śmierdzi, ale nie wiem co. Może niezgodność z RESTApi? Ale przecież to jest zgodne z asynchronicznymi api.

Do końca nie rozumiem w jaki sposób byś miał sprawdzić stan wykonywanego zadania bez wykonania kolejnego requesta do tego API, skoro dostęp do tego singletona byś miał z API z zdania. Chyba że miałbyś do niego dostęp inną drogą której nie umiem sobie wyobrazić.

somekind
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
0
Juhas napisał(a):

Sposób 1
Zapisać stan w bazie danych. Na końcu operacji zmienić stan na finished, a potem sprawdzić, czy jest finished, czy nie.
Problem
A co jeśli z jakiegoś powodu apka się wyrżnie i zostanie zrestartowana? Stan tamtej operacji cały czas będzie ustawiony na "running" i nie będzie można odpalić kolejnej bez grzebania w bazie danych

Ja tu widzę nawet większy problem - co z tą pierwszą, przerwaną operacją? Należy ją dokończyć? Zignorować? Jak to wpływa na następne operacje?

Jak to ma być jedna operacja jednocześnie na wiele godzin, to faktycznie prawdopodobnie HangFire powinien podołać, więc nie trzeba pisać nic swojego.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.