Pozwól mi podsumować to, co zrozumiałem z twoich wymagań:
- masz drzewo danych, gdzie każdy pojedynczy węzeł może być zmieniony asynchronicznie przez zbiór operacji (
capitalize_d
i remove_a
w swoim przykładzie),
- chcesz upewnić się, że każdy węzeł został poddany danej operacji przed zezwoleniem na następny.
Spędziłem 10 lat lub więcej projektowaniu czasie rzeczywistym oprogramowania wbudowanego, a wierzcie mi, wymagania w tym zakresie są meaner i scarrier niż cokolwiek większość programistów sieciowych będzie doświadczać w całym swoim życiu. To sprawia, że ostrzegam cię, że wydajesz się kierować poważnie złą drogą.
Jak mogę sobie wyobrazić, twoim problemem jest uporządkowanie zbioru pojedynczych danych w jakiejś znaczącej strukturze. W niektórych procesach zbierane są losowe bity informacji (tak zwane "węzły" w twoim przykładzie) iw pewnym momencie chcesz umieścić wszystkie te węzły w spójnej, monolitycznej strukturze danych (hierarchiczne drzewo w twoim przykładzie).
Innymi słowy, masz trzy zadania pod ręką:
- procesu pozyskiwania danych, które będą zbierać węzły asynchronicznie
- procesu produkcyjnego danych, który przedstawi spójny, wyrafinowane drzewa danych
- proces kontrolera, który synchronizuje pozyskiwanie i produkcję danych (ewentualnie bezpośrednio interfejs użytkownika, jeśli dwa powyższe procesy są wystarczająco inteligentne, ale nie licz na to zbyt wiele).
Moja rada: nie próbuj robić zakupu i produkcji w tym samym czasie.
Wystarczy dać wyobrażenie o koszmarze jesteś udaliśmy się do:
w zależności od sposobu działania są wyzwalane, istnieje możliwość, że drzewo nigdy nie będzie całkowicie przetwarzane przez danego działania . Powiedzmy, że oprogramowanie sterujące zapomina zadzwonić capitalize_d
na kilku węzłach, remove_a
po prostu nie dostać zielone światło
odwrotnie, jeśli ogień na drzewie w sposób losowy, to jest bardzo prawdopodobne, że niektóre węzły dostanie przetwarzane wielokrotnie , chyba śledzić zasięgu działania, aby zapobiec stosowaniu samej transformacji dwukrotnie na danym węźle
jeśli chcesz remove_a
przetwarzanie kiedykolwiek zacząć, może trzeba zapobiec oprogramowania sterującego wysyłać żadnych więcej capitalize_d
żądania, lub w przeciwnym razie światło może pozostać czerwone na zawsze. W ten sposób skończysz kontrolować przepływ swoich żądań (albo gorzej: nie zrobisz żadnego, a twój system może zamarznąć na śmierć, jeśli operacja wypłynie z miejsca, w którym trafiłeś przypadkowo).
jeśli operacja zmienia strukturę drzewa (oczywiście, jak to robi remove_a
), należy zapobiegać równoczesnemu dostępowi. Co najmniej należy zablokować poddrzewo, zaczynając od węzła, nad którym pracuje remove_a
, lub zezwolić na przetwarzanie poddrzewa, które może zostać asynchronicznie zmienione i/lub zniszczone.
Cóż, jest to możliwe. Widziałem dobrych ludzi zarabiających duże pieniądze, robiących wariacje na ten temat. Zwykle co tydzień spędzali kilka wieczorów, jedząc pizze na oczach swoich komputerów, ale hej, w ten sposób można odróżnić hakerów hard-hard od tłumu zjadaczy quiche, prawda? ...
Zakładam, że publikujesz Pytanie tutaj oznacza, że tak naprawdę nie chcesz tego robić. Teraz, jeśli szef ma, cóż, cytując słynnego androida, nie mogę cię okłamywać o twoich szansach, ale ... masz moje sympatie.
Poważnie ludzie. W ten sposób rozwiązam ten problem.
1) wykonanie zrzutu danych w danym momencie
można pozbyć się surowych danych przy użyciu tak wielu kryteriów, jak można (ostatnia akwizycja danych zbyt stary, niewłaściwego wejścia, co pozwala budować najmniejsze możliwe drzewo).
2) zbuduj drzewo wraz z migawką, a następnie zastosuj kolejne operacje capitalize_d, remove_a i camelize_z na tej migawce, kolejno.
Jednocześnie proces zbierania danych będzie nadal zbierać nowe węzły lub aktualizować istniejące, gotowe do wykonania następnej migawki.
Poza tym możesz przesunąć część przetwarzania do przodu. Oczywiście capitalize_d
nie wykorzystuje żadnej przewagi struktury drzewa, więc można zastosować capitalize_d
do każdego węzła w migawce, zanim drzewo zostanie nawet zbudowane. Możesz nawet zastosować niektóre transformacje wcześniej, tj. Na każdej zebranej próbce. Może to zaoszczędzić wiele czasu przetwarzania i złożoności kodu.
Aby zakończyć z odrobiną teoretyczna bełkot,
- Twoje podejście jest rozważenie drzewo dane wspólny obiekt, który powinien wspierać jednoczesnych acces z procesów akwizycji danych i produkcyjnych danych
- moje podejście jest aby proces rejestracji danych służą (asynchronicznie) zgodne zestawy danych do procesu produkcji danych, która może wtedy obsługiwać kolejno wspomnianego zestawu danych.
proces produkcji danych może być uruchamiany na żądanie (np. Gdy użytkownik końcowy kliknie przycisk "pokaż mi coś"), w którym to przypadku reaktywność byłaby raczej słaba: użytkownik utknąłby oglądając klepsydrę lub cokolwiek Web2.0 sexy kołowrotek do czasu potrzebnego do budowy i przetwarzania drewna (pozwala powiedzmy 7-8 sekund).
lub można aktywować proces produkcyjny danych okresowo (nakarmić ją nową migawkę co 10 sekund, okres bezpiecznie powyżej czas przetwarzania średniego zestawu danych). „Pokaż mi coś” przycisk będzie wówczas tylko zaprezentować ostatni zestaw ukończonych danych. Natychmiastowa odpowiedź, ale z danych, które mogą być starsze niż 10 sekund ostatnich otrzymaliśmy próbek.
rzadko widziałem przypadków, w których nie uznano za dopuszczalne, zwłaszcza gdy można produkować kilka złożonych danych operator potrzebuje kilkadziesiąt sekund do strawienia.
Teoretycznie moje podejście straci pewną reaktywność, ponieważ przetwarzane dane będą nieco przestarzałe, ale podejście do równoczesnego dostępu prawdopodobnie spowoduje jeszcze wolniejsze działanie oprogramowania (a na pewno 5-10 razy większe i większe).