Operacja na żywym organiźmie czyli wprowadzanie zmian w procesach

Jeśli zajmujemy się tworzeniem oprogramowania na zamówienie, zwłaszcza oprogramowania używanego do obsługi jakichś procesów w firmach, wcześniej czy później stajemy przed koniecznością dokonywania zmian w istniejących funkcjach systemu. Największe problemy w takich przypadkach wynikają z niekompatybilnością wstecz – gdy nowa logika systemu jest istotnie różna od tej która była wcześniej, a dane zebrane w aplikacji do tej pory mają ’starą’ strukturę i trzeba je jakoś zaktualizować aby system mógł działać dalej po wdrożeniu zmian. Jeśli aplikacja jest intensywnie modyfikowana a nie zapewnia jakiegoś sensownego podejścia do aktualizacji to raczej szybko doprowadzimy do koszmarnej sytuacji kiedy 5% czasu poświęcamy na implementację zmiany, a pozostałe 95% na migrację istniejących danych oraz obsługę wygenerowanych przy tej okazji problemów. Dziś spróbuję podpowiedzeć jak wykorzystując NGinn można sobie ułatwić przyszły rozwój systemu.

W przypadku NGinn mówimy o aktualizacji procesów. Załóżmy że działamy w firmie i mamy zaimplementowany proces który jest w użyciu od dłuższego czasu – to oznacza że mamy mnóstwo spraw obsługiwanych tym procesem, część z tych spraw jest zakończona a część jest w trakcie realizacji na różnych etapach. Jeśli tak po prostu zmodyfikujemy definicję tego procesu to prawdopodobnie spowodujemy że toczące się sprawy staną się niekompatybilne z nową definicją i z powodu błędów nie będą mogły się zakończyć. Tego bardzo nie chcemy, bo jeśli to my dostarczamy oprogramowanie to po takim wdrożeniu zostaniemy zmuszeni do posprzątania całego bałaganu. O tej strategii nie będę więcej pisał, wszyscy wiedzą że można jej użyć w każdym przypadku ale lepiej wiedzieć co się robi. Przyjrzyjmy się lepiej innym sposobom:

1. Wersjonowanie procesu

NGinn pozwala używać kilku wersji definicji tego samego procesu (w tym celu jest numerek wersji w nazwie pliku z definicją), więc w wielu przypadkach najprościej jest zdefiniować nową wersję procesu która będzie używana dla spraw które dopiero zostaną zarejestrowane. Aktualnie toczące się sprawy pozostają na starej definicji procesu i mogą spokojnie się zakończyć ‘po staremu’. Unikamy w ten sposób jakiejkolwiek migracji danych więc jeśli uda się klienta przekonać do takiego rozwiązania sprawy to mamy sukces gwarantowany.

2. Anulowanie i ponowne uruchomienie

W niektórych przypadkach można rozwiązać problem aktualizacji poprzez anulowanie aktualnie toczących się spraw i ponowne ich uruchomienie już na nowej definicji procesu. Jak to zrobić w NGinn? Ano, narzędzia do tego nie ma, ale jest API pozwalające anulować procesy i je uruchamiać oraz ‘grzebać’ w danych procesów i zadań. Zatem można stworzyć sobie narzędzie które nam taką migrację obsłuży. Problem może wystąpić jeśli do uruchomienia procesu w nowej wersji konieczne są inne dane wejściowe – wtedy trzeba też dokonać konwersji i ewentualnego uzupełnienia danych. Istotna rzecz: NGinn nie zapamiętuje oryginalnych wartości danych wejściowych procesu – pamięta tylko ich aktualne wartości. Zatem jeśli podczas działania procesu zmienne wejściowe są modyfikowane to może się okazać że stracimy informacje potrzebne do uruchomienia tego samego procesu w nowej wersji. Taka sytuacja jednak jest dość rzadka, zwykle dane wejściowe istotne dla sprawy nie zmieniają się w trakcie jej realizacji.

3. Użycie Barier

Jeśli koniecznie chcemy aktualizować toczące się sprawy ‘na żywca’, to bardzo nam przeszkadza fakt że znajdują się one na rozmaitych etapach realizacji i trzeba to uwzględnić wprowadzając poprawkę – po prostu musi być ścieżka migracji dla każdego etapu na którym może się znajdować sprawa. W niektórych przypadkach nie trzeba nic robić – na przykład jeśli sprawa znajduje się na początku procesu, a my modyfikujemy jego końcówkę to nic złego się nie wydarzy. Zatem jeśli mieli byśmy taką sytuację że wszystkie sprawy znajdują się poza regionem procesu który modyfikujemy – tzn albo jeszcze do tego regionu nie doszły, albo już go opuściły – to zwykle migracja była by o wiele łatwiejsza albo wręcz niepotrzebna.

Żeby stworzyć taką możliwość w NGinn została wprowadzona funkcja “barier”. Bariera zatrzymuje nam działanie procesów w określonym miejscu i pozwala je wznowić po usunięciu bariery. Barierę stawiamy w wybranym miejscu, bądź miejscach, w procesie (chodzi o te kółeczka, czyli places).Jeśli w danym miejscu postawiona jest bariera to tokeny z tego miejsca nie mogą iść dalej, czyli nie jest uruchamiane zadanie wychodzące z tego miejsca. Tokeny czekają na usunięcie bariery czyli cała sprawa jest wstrzymana, natomiast sprawy które zdążyły pójść dalej zanim postawiliśmy barierę kontynuują proces bez przeszkód.

Jak tego użyć? Stawiamy barierę przed regionem w procesie który modyfikujemy i czekamy aż wszystkie sprawy opuszczą ten region (czyli tokeny we wszystkich instancjach tego procesu znajdą się poza modyfikowanym regionem). Bariera gwarantuje że żadne nowe tokeny nie napłyną więc oczyszczenie naszego pola działania jest tylko kwestią czasu. Wtedy zmieniamy definicję procesu i zdejmujemy barierę – wypuszczone sprawy potoczą się już wg zaktualizowanej definicji.

Czy to znaczy że właśnie opisałem stuprocentowo skuteczny sposób na aktualizację logiki systemu? No nie do końca… Przede wszystkim nie było mowy o danych. Co z tego że zaktualizujemy definicję procesu, kiedy w nowej wersji będą potrzebne dodatkowe dane (których przecież nie ma w aktualnie toczących się sprawach)? Nie będziemy w stanie ruszyć do przodu bez uzupełnienia tych danych. Do uzupełnienia czy modyfikacji danych musimy jednak zbudować własne narzędzie – NGinn daje do tego API, ale to jakie zmiany wprowadzić w danych musimy wymyślić sami. Bariera może się też tutaj przydać – jeśli sobie ’spiętrzymy’ sprawy w określonym miejscu to przynajmniej będziemy wiedzieli w których zadaniach należy zaktualizować dane.

Let us talk about
Name and Mail are required
Join the discuss