Friday 17 November 2017

Erlang system handlowy


25 maja 16 00 BST 15 00 UTC 17 00 CET 08 00 PDT Sportrisq jest brokerem i dystrybutorem rozwiązań i produktów zarządzania ryzykiem dla branży sportowej Posłuchaj CTO Justin Worall opisuje proces migracji dwóch podstawowych komponentów platformy z Pythona do Erlang problemy z tym związane, postrzegane zalety Erlanga w takich sytuacjach, proces podejmowania decyzji, projektowanie aplikacji i wyniki. W trakcie seminarium internetowego nauczysz się. Proces migracji komponentów Pythona o niskiej latencji do Erlangu. Proces podejmowania decyzji. Aplikacja projekty i rezultaty. Poinformuj o tym Erlang. Hey tam jest, że Twój Javascript jest wyłączony To w porządku, witryna działa bez niego Jednak wolałabyś go czytać z podświetleniem składni, co wymaga JavaScript. Rage Against The Finite State Machines. FSM maszyny skończonej nie jest maszyną, ale ma ograniczoną liczbę stanów, w których zawsze znalazłem maszyny stanu skończonego, łatwiejsze do zrozumienia za pomocą wykresów i diagramów. Przykładem może być uproszczony schemat bardzo głupiego psa jako maszyny państwowej. Tutaj pies ma trzy państwa siedzące, szczekające lub zwodzące się z jego ogonem Różne zdarzenia lub wejścia mogą zmusić go do zmiany stanu. Jeśli pies jest spokojnie siedzący i widzi wiewiórkę, zacznie szczekać i nie powstrzymaj, dopóki nie będziesz się znowu bawić. Jeśli pies siedzi i ty go kochasz, nie mamy pojęcia, co może się zdarzyć W świecie Erlang, pies mógłby zepsuć się i ostatecznie zostać zrestartowany przez jego opiekun W prawdziwym świecie, który byłby dziwnym wydarzeniem, ale twój pies wróciłby po przejechaniu przez samochód, więc to nie jest złe. Oto schemat stanów kotów do porównania. Ten kot ma jedno państwo , a żadne zdarzenie nigdy się nie zmieni. Użycie maszyny stanu kota w Erlangu to zabawne i proste zadanie. Możemy spróbować tego modułu, aby zobaczyć, że kot naprawdę nigdy nie daje crap. The samo można zrobić dla psa FSM z wyjątkiem więcej stany są dostępne. Nie powinno być stosunkowo proste do dopasowania każdego z państw i tr ansitions do tego, co było na diagramie powyżej Oto FSM w use. You można postępować zgodnie ze schematem, jeśli chcesz, zwykle robię, pomaga upewnić się, że nic nie jest wrong. That naprawdę core wdrażania FSMs jak Erlang procesów There są rzeczy, które można było zrobić inaczej możemy przenieść stan w argumentach funkcji stanu w sposób podobny do tego, co robimy z serwerami pętli głównej Możemy również dodać funkcje init i kończyć, obsługiwać aktualizacje kodu, etc. Another różnica pomiędzy psem a kotem FSM jest taka, że ​​zdarzenia kotów są synchroniczne, a zdarzenia psów są asynchroniczne. W prawdziwym FSM oba mogą być używane w sposób mieszany, ale udałem się na najprostszą reprezentację z czystego niewłaściwego lenistwa inne formy zdarzenia przykłady nie pokazują globalnych zdarzeń, które mogą się zdarzyć w każdym stanie. Przykładem takiego zdarzenia może być sytuacja, gdy pies dostaje wąchanie po jedzeniu Po ​​zapoczątkowaniu zapachu, niezależnie od stanu psa , on idzie szukając źródła jedzenia. Teraz nie poświęcaliśmy zbyt wiele czasu na wdrożenie tego wszystkiego w naszym FSM na papierze na napkin. Zamiast tego przenosimy się bezpośrednio do zachowania genfsm. Zachowanie genfsm jest podobne do genserver, jest to jego specjalistyczna wersja Największą różnicą jest to, że zamiast obsługiwać połączenia i odrzuty, zajmujemy się synchronicznymi i asynchronicznymi zdarzeniami Podobnie jak nasze przykłady psów i kotów, każde państwo jest reprezentowane przez funkcję Ponownie, przechodzimy przez wywołania zwrotne, których potrzebują nasze moduły do wdrożenia w celu pracy. Jest to ta sama init 1, jaka jest używana dla serwerów rodzajowych, z wyjątkiem akceptowanych wartości zwrotu i Koniec tupli działa w taki sam sposób, jak dla genserver s, a hibernacja i limit czasowy zachowują tę samą semantykę. nowością jest tutaj, że nazwaName StateName zmienna jest atomem i reprezentuje następną funkcję callback, która ma być wywołana. Funkcje StateName 2 i StateName 3 są nazwami zastępczymi i decydujesz, jakie będą ich nazwy Pozwólmy przypuśćmy, że init 1 Funkcja zwraca krotkę Oznacza to, że maszyna stanu skończonego będzie w stanie siedzącym Nie jest to ten sam stan jak widzieliśmy w przypadku genserver, jest raczej odpowiednikiem kory siedzącej i stanów pałeczek poprzedniego psa FSM Te stany dyktują kontekst, w którym obsłużysz określone zdarzenie. Przykładem tego może być ktoś, kto dzwoni do Ciebie w telefonie Jeśli znów jesteś w stanie spania w sobotę rano, twoja reakcja może zadzwonić do telefonu Jeśli państwo czeka na pracę wywiad, masz szanse wybrać telefon i odpowiedzieć grzecznie Z drugiej strony, jeśli jesteś w stanie martwym, to jestem zaskoczony możesz nawet przeczytać ten tekst na wszystkich. Wróć do naszego FSM Funkcja init 1 powiedziała, że ​​powinniśmy w stanie siedzącym Każdorazowo, gdy proces genfsm odbierze zdarzenie, funkcja 2 lub siedząca 3 zostanie nazwana Funkcja 2 posiedzenia jest wywoływana dla zdarzeń asynchronicznych i siedzi 3 dla synchronicznych. Argumenty siedzenia 2 lub zasadniczo nazwaNazwa 2 to Zdarzenie faktycznego wysłania wiadomości jako zdarzenia, a StateData dane, które zostały przeniesione przez wywołania 2, mogą zwracać krotki. Argumenty siedzenia 3 są podobne, z wyjątkiem sytuacji, w której znajduje się zmienna typu From z Event and StateData Zmienna From jest używany dokładnie w taki sam sposób, jak dla genserver s, włącznie z odpowiedzią genfsm 2 Funkcje StateName 3 mogą zwracać następujące krotki. Zwróć uwagę, że nie ma limitu, ile z tych funkcji możesz mieć, o ile są one eksportowane Atomy zwrócone jako NextStateName w krotkach określą, czy funkcja zostanie wywołana, czy nie. W ostatniej sekcji wspomniałem o globalnych zdarzeniach, które mogłyby wywołać konkretną reakcję, bez względu na to, jakiego stanu jesteśmy w psie pachnące jedzenie spadnie co to jest robi i zamiast tego poszukać żywności Dla tych zdarzeń, które powinny być traktowane w ten sam sposób w każdym stanie, handleevent 3 callback jest tym, co chcesz Funkcja odbiera argumenty podobne do StateName 2 z wyjątkiem tha t akceptuje zmienną StateName pomiędzy nimi, informując o stanie stanu, w którym zostało odebrane zdarzenie Zwraca te same wartości, co nazwaNazwa 2.Czasami zwrotu wywołania handlesyncevent 4 jest nazwaNazwa 3, co to jest handleevent 2 to StateName 2 Obsługuje synchroniczne zdarzenia globalne , bierze te same parametry i zwraca ten sam typ krotek jako nazwęNie 3.Naw dobry czas, aby wyjaśnić, w jaki sposób wiemy, czy zdarzenie ma charakter globalny, czy też oznacza to wysłanie do określonego stanu. Aby to stwierdzić, możemy spojrzeć w funkcji służącej do wysyłania zdarzenia do zdarzeń asynchronicznych FSM mających na celu dowolną funkcję państwaName 2 są wysyłane z zdarzeniami synchronizacji sendevent 2, które mają być pobrane przez stateName 3, są wysyłane z syncsendevent 2-3. Dwa równorzędne funkcje dla zdarzeń globalnych są sendallstateevent 2 i syncsendallstateevent 2-3 dość długie name. This działa dokładnie tak samo, jak to zrobić dla genserver s, z wyjątkiem tego, że wymaga dodatkowego parametru stanu kiedy nazywa się jak kodchange OldVersion, StateName, Data, E xtra i zwraca krotkę formularza. Powinno to znowu działać trochę jak to, co mamy dla serwerów typu generic, które kończą się 3 powinny zrobić przeciwieństwo init 1.It s czas, aby umieścić to wszystko w praktyce Wiele tutoriale Erlang o finite - że większość programistów będzie rzadko musiała radzić sobie z przełącznikami telefonicznymi dla maszyn stanowych Z tego powodu przyjrzymy się przykładowi, który jest bardziej odpowiedni dla wielu programistów, które zaprojektujemy i wdrożyć system handlu przedmiotami dla fikcyjnej i nieistniejącej gry wideo. Projekt, który wybrałem, jest nieco trudny niż używanie brokera, za pomocą którego gracze kierują trasami i potwierdzeniami, które szczerze mówiąc byłyby łatwiejsze, zamierzamy wdrożyć serwer, w którym obaj gracze rozmawiają ze sobą bezpośrednio, co miałoby tę zaletę, że można je rozpowszechniać. Ponieważ implementacja jest trudna, będę opisywał to, rodzaj problemów, które mają być f aced i sposoby ich naprawienia. Przede wszystkim powinniśmy określić czynności, które mogą być dokonane przez naszych graczy podczas handlu Pierwszy prosi o utworzenie handlu Inny użytkownik powinien mieć również możliwość zaakceptowania tego handlu Wygraliśmy nie daj im prawa do odmowy handlu, bo dlatego, że chcemy zachować proste rzeczy Łatwo będzie dodać tę cechę, gdy wszystko się skończy. Po ustaleniu handlu nasi użytkownicy powinni mieć możliwość negocjacji z każdym inne Oznacza to, że powinni mieć możliwość składania ofert, a następnie wycofać je, jeśli chcą, gdy obaj gracze są zadowoleni z oferty, mogą zadeklarować, że są gotowi do sfinalizowania handlu Dane należy następnie zapisać gdzieś po obu stronach W dowolnym momencie z czasem powinno też mieć sens dla każdego z graczy, aby anulować cały handel Niektóre pleb mogłyby oferować tylko przedmioty uważane za niegodne drugiej stronie, która może być bardzo zajęci, więc powinno być możliwe backhand z zasłużoną odwołanie. W krótkim, następujące działania powinny być possible. ask dla trade. accept trade. offer items. retract offer. declare self jako ready. brutally anulować trade. Now, gdy każdy z tych działań jest podjęte, inny gracz FSM należy uświadomić To ma sens, ponieważ gdy Jim mówi, że jego FSM przesłał przedmiot Carlowi, Carl's FSM musi być o tym świadomy Oznacza to, że obaj gracze mogą rozmawiać z własnym FSM, który porozmawia z innymi FSM. nam coś trochę podobnego do tej. Pierwsza rzecz, którą należy zauważyć, gdy mamy dwa identyczne procesy komunikujące się ze sobą jest to, że musimy uniknąć połączeń synchronicznych jak najwięcej Powodem tego jest, że jeśli Jim s FSM wysyła wiadomość do Carl s FSM, a następnie czeka na odpowiedź, jednocześnie Carl's FSM wysyła wiadomość do serwera Jim's FSM i oczekuje na własną odpowiedź, kończąc na oczekiwanie na drugą bez odpowiedzi na to, co skutecznie zamarza obydwa FSM Jednym z rozwiązań jest poczekać na limit czasu, a następnie przejść dalej , ale wtedy pozostaną resztki wiadomości w obu skrzynkach pocztowych, a protokół zostanie pomieszany. To z pewnością jest robak robaków, a więc chcemy go uniknąć. Najprostszym sposobem na to jest uniknięcie wszystkich synchronicznych komunikatów i przejście w pełni asynchroniczny Zauważ, że Jim może nadal wykonywać synchroniczne wezwanie do własnego FSM nie ma tu żadnego zagrożenia, ponieważ FSM nie potrzebuje dzwonić do Jima i dlatego nie może nastąpić żaden impas. Gdy dwa z tych FSM komunikują się razem, cała wymiana może wyglądać trochę jak to. Wszystkie FSM są w stanie bezczynności. Kiedy poprosisz Jim o handel, Jim musi zaakceptować, zanim sprawy się poruszyją. Wtedy obie z nich mogą zaoferować przedmioty lub wycofać je. Kiedy obaj deklarują gotowość, handel może się odbyć Jest to uproszczona wersja tego wszystkiego, co może się zdarzyć i zobaczymy wszystkie możliwe przypadki z większą szczegółowością w następnych akapitach. Tu jest trudna część definiująca schemat stanowy i jak przebiegają przemiany stanowe. Zwykle jest to dobre myślenie, ty musimy myśleć o wszystkich małych rzeczach, które mogą się niegodzić Niektóre rzeczy mogą się nie zgadzać nawet po wielokrotnym przeglądzie Z tego powodu po prostu postawię ten, który zdecydowałem się tu wdrożyć, a następnie wytłumaczyć. maszyny państwowe zaczynają się w stanie bezczynności W tym momencie możemy zadać pytanie innym graczom, aby mogli negocjować z nami. Wchodzimy w tryb oczekiwania, aby nasilić oczekiwanie na odpowiedź, gdy nasz FSM prześle żądanie Kiedy inne FSM wysyła odpowiedź, nasza może przełączyć się na negocjacje. Inni gracze powinni też być w negocjacjach po tym Oczywiście, jeśli możemy zaprosić innych, inni mogą nas zaprosić Jeśli wszystko pójdzie dobrze, powinno to wyglądać tak. całkiem odwrotnie, jak dwa wcześniejsze diagramy stanowe w jednym Pamiętaj, że spodziewamy się, że gracz zaakceptuje ofertę w tym przypadku Co się stanie, jeśli przez czystą szczęście prosimy innego gracza, aby z nami handlował równocześnie, prosi nas handlu. Co się tutaj dzieje, że obaj klienci poproś własnego FSM o negocjowanie z drugą osobą Gdy tylko zostaną wysłane prośby o przesłanie wiadomości, obie FSM przełączają się w stan bezczynności Następnie będą mogli przetworzyć pytanie negocjacyjne Jeśli przejrzymy poprzednie diagramy stanu, zobaczymy, że ta kombinacja zdarzenia są jedynym momentem, w którym otrzymamy prośbę o negocjowanie wiadomości w stanie bezczynności W konsekwencji wiemy, że otrzymanie tych wiadomości w stanie bezczynności oznacza, że ​​straciliśmy stan wyścigu i możemy założyć, że obaj użytkownicy chcą ze sobą rozmawiać Możemy przenieść obie z nich negocjować stan Hooray. So teraz negocjujemy Zgodnie z listą działań, o których wspomniałem wcześniej, musimy wspierać użytkowników oferujących przedmioty, a następnie wycofywać ofertę. Wszystko to robi przekazuje nasz komunikat klienta do innego FSM. Zarówno maszyny stanu skończonego będą musieli trzymać listę przedmiotów oferowanych przez jednego z graczy, więc mogą aktualizować tę listę podczas odbierania takich wiadomości. Pozostajemy w stanie negocjacji, po tym może drugi gracz chce zaoferować również takie przedmioty. Tu nasz FSM działa w podobny sposób To jest normalne Kiedy się zmęczymy oferowaniem rzeczy i myślimy, że jesteśmy na tyle szczodry, musimy powiedzieć, że jesteśmy gotowi do oficjalnego handlu Ponieważ musimy zsynchronizować obu graczy, będziemy musieli użyj państwa pośredniczącego, tak jak robiliśmy to bezczynnie i bezczynnie. To, co robimy, jest takie, że gdy tylko nasz gracz jest gotowy, nasi FSM pytają o Jim's FSM, jeśli jest gotowy. W oczekiwaniu na odpowiedź nasz własny FSM wpada w stan oczekiwania odpowiedź otrzymamy będzie zależeć od stanu FSM firmy Jim, czy to jest w stanie oczekiwania, to powiedz nam, że jest gotowe. Inaczej, powiedz nam, że nie jest jeszcze gotowe. Właśnie to, co nasze FSM automatycznie odpowiada na Jim, jeśli on pyta nas, czy jesteśmy gotowi, gdy negocjujemy stan. Nasza skończona maszyna państwowa pozostanie w trybie negocjacji, dopóki nasz odtwarzacz nie powie, że jest gotowy. Załóżmy, że to zrobił i jesteśmy teraz w stanie oczekiwania. Jeszcze tam nie ma. Oznacza to, że kiedy zadeklarowaliśmy, że jesteśmy gotowi, poprosimy Jima, czy też będzie gotowy, a jego FSM będzie nie odpowiedziałem jeszcze. Je nie jest gotowy, ale nie możemy zrobić wiele, ale czekaj Czekając na Jima, który wciąż negocjuje przy okazji, jest możliwe, że spróbuje przesłać nam więcej elementów lub może odwołać jego poprzednich ofert. Oczywiście chcemy uniknąć Jim usunięcia wszystkich jego elementów, a następnie kliknięcia I'm ready, wkręcając nas w procesie Jak tylko zmieni oferowanych przedmiotów, wracamy do stanu negocjacji, więc możemy albo zmodyfikować naszą własną ofertę lub zbadaj obecną i zadecydujemy, czy jesteśmy gotowi do spłukiwania i powtarzania. W pewnym momencie Jim będzie gotowy do sfinalizowania handlu również wtedy, gdy jego sprawa stanie się zadaniem, jeśli jesteśmy gotowi. FSM to odpowiedź, że jesteśmy w stanie gotowości Jesteśmy w stanie oczekiwania i nie chcemy przejść do stanu gotowości Dlaczego tak jest, ponieważ istnieje potencjalny stan wyścigowy Wyobraźmy sobie, że następująca sekwencja zdarzeń ma miejsce, nie wykonując tego niezbędnego kroku. jest nieco skomplikowane, więc wyjaśnię ze względu na wa y otrzymamy wiadomość, możemy tylko przetworzyć ofertę przedmiotu po tym, jak zadeklarowaliśmy, że jesteśmy gotowi, a także po tym, jak Jim zadeklarował, że jest gotowy Oznacza to, że gdy tylko przeczytamy informację o ofercie, wycofamy się, aby negocjować stan W tym czasie Jim powiedziano nam, że jest gotowy Jeśli miałby zmienić stan tam właśnie i przejść dalej, tak jak to zostało zilustrowane powyżej, dać się zaczekać czekając na nieskończoność, podczas gdy nie wiedzieliśmy, co to do diabła zrobić Może to się zdarzyć tak, jak to się dzieje wokół Ugh. sposobem na rozwiązanie tego problemu jest dodanie jednej warstwy wewnętrznej Dzięki David Wheeler Dlatego pozostajemy w trybie oczekiwania i wysyłamy gotowe, jak pokazano na poprzednim diagramie stanu Oto jak poradzimy sobie z tym gotową wiadomością, zakładając, że byliśmy już gotowi ponieważ powiedzieliśmy nasz FSM, że jesteśmy gotowi wcześniej. Kiedy otrzymamy gotowość od innego FSM, wysyłamy gotowe z powrotem To jest, aby upewnić się, że wygrałem t mają podwójny stan wyścigu wspomnianego wyżej Stworzy to zbędny gotowy messa ge w jednym z dwóch modułów FSM, ale musimy to zignorować w tym przypadku. Następnie wyślemy komunikat ack, a program Jim's FSM zrobi to samo przed przejściem do stanu gotowości. Powodem, dla którego ten komunikat ack istnieje, jest niektóre szczegóły implementacji synchronizacji klientów I've umieścić go na diagramie dla dobra być poprawne, ale ja wygrałem t wyjaśnić to dopóki Zapomnij o tym teraz W końcu udało nam się zsynchronizować obu graczy Whew. So teraz jest stan gotowy Ten jest trochę specjalny Obydwaj gracze są gotowi i w zasadzie dają maszyny skończonej stanu wszystkie kontrolki, których potrzebują To pozwala nam zaimplementować bastardyzowaną wersję zobowiązania dwufazowego, aby upewnić się, że wszystko się skończyło, tworząc oficjalną oficjalność. opisany powyżej będzie raczej uproszczony Pisanie prawdziwie poprawnego zobowiązania dwufazowego wymagałoby dużo większego kodu, niż to, co jest konieczne do zrozumienia maszyn skończonych. Ostatecznie musimy tylko pozwolić, aby transakcja została odwołana w dowolnym momencie To oznacza tha t w jakikolwiek sposób, niezależnie od stanu, w którym się znajdujemy, będziemy słuchać wiadomości anulującej z obu stron i zamknij transakcję Powinniśmy również być uprzejmością, aby druga strona znała nas, że odeszliśmy przed odejściem. informacji, aby wchłonąć od razu Nie martw się, jeśli zajmie to chwilę, aby w pełni zrozumieć To zajęło mnóstwo ludzi, aby spojrzeć na mój protokół, aby sprawdzić, czy to było dobre, a nawet wtedy wszyscy ominęliśmy kilka warunków wyścigowych, które potem złapałem kilka dni później podczas przeglądania kodu podczas pisania tego tekstu To normalne, że trzeba go przeczytać więcej niż jeden raz, zwłaszcza jeśli nie są używane do protokołów asynchronicznych Jeśli tak jest, w pełni zachęcam do spróbowania i zaprojektowania własnego protokołu Następnie zadaj sobie pytanie, co się dzieje, jeśli dwoje osób wykona te same czynności bardzo szybko Co zrobić, jeśli łańcuchzy dwa inne wydarzenia szybko Co zrobić z wiadomościami, których nie poradzę przy zmianie stanów Widzisz, że złożoność rośnie naprawdę szybko Możesz znaleźć rozwiązanie podobne kopać, być może zakład Po pierwsze, daj mi znać, czy tak jest. Nie ważne co to jest wynik, to bardzo ciekawa rzecz, nad którą pracujemy, a nasze FSM są wciąż stosunkowo proste. Kiedy już wszystko przeanalizowaliśmy, jeśli jesteś rebelianckim czytelnikiem, możesz przejdź do następnej sekcji, w której implementujemy system gier Teraz możesz zrobić miłą przerwę na kawę, jeśli chcesz to zrobić. Pierwszą rzeczą, którą należy wykonać, aby wdrożyć nasz protokół z genfsm OTP to utworzenie interfejsu będą 3 rozmówcami dla naszego modułu odtwarzacza, zachowania genfsm i innych graczy FSM Musimy tylko wyeksportować funkcję odtwarzacza i funkcji genfsm, chociaż to dlatego, że inne FSM będą również działać w module tradefsm i mogą je uzyskać od wewnątrz. Je to jest nasz interfejs API Można zobaczyć, że planuję posiadanie pewnych funkcji zarówno synchronicznych jak i asynchronicznych Jest to głównie dlatego, że chcemy, aby nasz klient zadzwonił do nas synchronicznie w niektórych przypadkach, ale inny FSM może to zrobić asynchronicznie synchronizacja klienta ronous upraszcza całą naszą logikę, ograniczając liczbę sprzecznych wiadomości, które mogą być wysyłane jeden po drugim We 'll get there Pozwól najpierw na wdrożenie rzeczywistego publicznego API zgodnie z protokołem zdefiniowanym powyżej. To jest dość standardowe wszystkie te funkcje genfsm zostały już omówione, z wyjątkiem startu 3-4 i startlink 3-4, które sądzę, że można to zrozumieć w tym rozdziale. Następnie będziemy implementować funkcje FSM do FSM Pierwsze z nich mają związek z ustawieniami handlowymi, kiedy najpierw chcemy zapytać innym użytkownikowi dołączyć do nas w handlu. Pierwsza funkcja prosi drugą firmę pid, jeśli chce handlować, a druga jest używana do odpowiedzi na nią asynchronicznie. Oczywiście możemy pisać funkcje oferowane i anulować oferty. nasz protokół powyżej, tak właśnie powinny być takie. Więc teraz, gdy już wykonaliśmy te połączenia, musimy skupić się na reszcie pozostałych pozostałych odwołań odnosi się do bycia gotowym, czy nie, a ostatecznym zobowiązaniem się do ponownego popełnienia, zważywszy na nasz protokół powyżej , mamy trzy połączenia ar eyouready, które mogą mieć odpowiedzi na notyet lub gotowe. Pozostały tylko te funkcje, które mają być używane przez oba FSM przy wykonywaniu zobowiązania w stanie gotowości. Ich dokładne wykorzystanie zostanie opisane bardziej szczegółowo później, ale na razie nazwy i schemat stanu sekwencji z wcześniejszej strony powinien być wystarczający Niemniej jednak można nadal przepisać je do swojej własnej wersji programu Tradefsm. Oh, a także funkcję uprzejmości pozwalającą nam ostrzec inne FSM, które anulowaliśmy handel. Możemy teraz przenieść się do naprawdę interesująca część wywołań zwrotnych genfsm Pierwszym wywołaniem zwrotnym jest init 1 W naszym przypadku będziemy chcieli, aby każdy FSM posiadał nazwę dla użytkownika reprezentowanego w ten sposób, że nasze dane będą ładniejsze w danych, które nie przechodzą do siebie Co jeszcze robimy Chcesz zachować pamięć W naszym przypadku chcemy, aby inne pid, rzeczy, które oferujemy, a pozostałe pozostałe oferty. Dodamy również referencję monitora, abyśmy mogli przerwać pracę, jeśli inne matryce i pola , używane do opóźnienia odpowiedzi. W cas e of init 1 będziemy tylko troszczyć się o nasze imię już teraz Zauważ, że zaczniemy w stanie bezczynności. Następne wywołania zwrotne do rozważenia byłyby państwami Do tej pory opisałem przejścia stanu i wywołania, które można dokonać, ale my musimy mieć pewność, że wszystko idzie w porządku Najpierw napiszemy kilka funkcji użytkowych. I możemy zacząć od stanu bezczynności. Ze względu na konwencję, najpierw przedstawię wersję asynchroniczną. Nie musisz się martwić o wszystko, ale drugi gracz z prośbą o handel z własnym odtwarzaczem, jeśli spojrzysz na funkcje API, użyje synchronicznego połączenia. A monitor jest skonfigurowany tak, abyśmy mogli obsłużyć innych umierających, a jego adresat został zapisany w danych FSM wraz z innymi pidami przed przejściem do stanu bezczynności Zauważ, że zgłosimy wszystkie nieoczekiwane zdarzenia i zignorujemy je, pozostając w stanie, w którym się znajdowaliśmy Już możemy mieć kilka z wiadomości zespołu, które mogłyby być rezultatem warunków rasowych Zazwyczaj zignorować je , ale możemy łatwo je pozbyć To po prostu lepiej nie rozbić całego FSM na te nieznane, ale nieco oczekiwane komunikaty. Kiedy nasz klient prosi FSM o skontaktowanie się z innym graczem w celu handlu, wyśle ​​zdarzenie synchroniczne Wymagane będzie odblokowanie bezczynności 3. Postępujemy w sposób podobny do wersji asynchronicznej, chyba że musimy zapytać drugą stronę, czy chcą negocjować z nami, czy nie. Zauważysz, że nie odpowiadamy na klienta jeszcze to dlatego, że nie mamy nic ciekawego do powiedzenia i chcemy, aby klient zamknęła się i czekał na akceptację handlu przed zrobieniem czegoś. Odpowiedź zostanie wysłana tylko wtedy, gdy druga strona zaakceptuje, kiedy tylko będziemy w stanie gotowości. Kiedy tam jesteśmy, mamy do czynienia z innymi akceptującymi negocjacje, a inni proszą o wynegocjowanie wyniku choroby wyścigowej, jak opisano w protokole. Daje to nam dwa przejścia do stanu negocjacji, ale pamiętaj, że musimy użyć odpowiedzi genfsm 2 odpowiedzieć naszym klientom powiedzieć to s oka y, aby rozpocząć oferowanie przedmiotów Istnieje również sprawa naszego klienta FSM akceptującego handel sugerowany przez drugą stronę. Zainteresowanie przejdzie do stanu negocjacji W tym miejscu musimy obsługiwać zapytania asynchroniczne w celu dodawania i usuwania elementów pochodzących zarówno z klient i inne FSM Nie zdecydowaliśmy jeszcze, jak przechowywać pozycje Ponieważ jestem trochę leniwy i przypuszczam, że użytkownicy wygrywali handel, że wiele elementów, proste listy to zrobią na razie Teraz możemy zmienić nasze myśli w późniejszym punkcie , więc warto byłoby zawinąć operacje na własne rzeczy Dodając następujące funkcje na dole pliku, dodając poniższe funkcje z informacją 3 i niespodziewany 2.Simple, ale mają one na celu oddzielenie akcji dodawania i usuwania elementów z ich implementacja list Możemy łatwo przenieść się do proplistów, tablic lub dowolnej struktury danych, nie zakłócając reszty kodu. Korzystając z obu tych funkcji, możemy wdrożyć propozycję i usunięcie elementów. Jest to brzydki aspekt wykorzystania asynchronicznego bałaganu wieki z obu stron Jeden zestaw wiadomości ma formę i cofanie, a drugi ma co robić i cofnąć Jest to całkowicie arbitralne i używane tylko do różnicowania komunikacji między odtwarzaczami a FSM i łączności FSM-to-FSM Zauważ, z naszego własnego odtwarzacza musimy powiedzieć drugą stronę o zmianach, jakie ponownie wykonujemy. Kolejną odpowiedzialnością jest obsłużyć wiadomość, którą wspomnieliśmy w protokole. Jest to ostatnie asynchroniczne zdarzenie, które będzie obsługiwane w stanie negocjacji. Jak opisano w protokół, gdy nie jesteśmy w stanie oczekiwania i otrzymujemy tę wiadomość, musimy odpowiedzieć z notyet Dostawialiśmy również dane handlowe do użytkownika, aby można było podjąć decyzję. Gdy taka decyzja zostanie podjęta, a użytkownik jest gotowy, gotowe wydarzenie zostanie wysłany Ten powinien być synchroniczny, ponieważ nie chcemy, aby użytkownik nadal modyfikował swoją ofertę, dodając elementy, twierdząc, że jest gotowy. W tym momencie należy przejść do stanu oczekiwania. Zauważ, że czekając tylko na inne nie jest interesujące Oszczędzamy Od zmiennej, dzięki czemu możemy używać go z odpowiedzią genfsm 2, gdy mamy coś do powiedzenia klientowi. Stan oczekiwania to śmieszna bestia Nowe przedmioty mogą być oferowane i wycofane, ponieważ inny użytkownik może nie być gotowy ma sens, aby automatycznie wycofać się do stanu negocjacji Byłoby zasmakowane, że otrzymaliśmy wspaniałe rzeczy, tylko dla drugiego, aby je usunąć i zadeklarować gotowość do kradzieży, kradzież naszego łupu. Wracając do negocjacji to dobra decyzja. coś znaczącego i odpowiadamy na odtwarzacz z współrzędnymi, które przechowywaliśmy w następnym zestawie wiadomości, które musimy martwić to te związane z synchronizacją obu FSM, aby mogły przejść do stanu gotowości i potwierdzić handel Dla tego powinniśmy naprawdę skoncentrujmy się na wcześniej zdefiniowanym protokole. Trzy komunikaty, które moglibyśmy mieć, są już dlatego, że inny użytkownik po prostu zadeklarował, że jest gotowy, nie dlatego, że zapytaliśmy drugiego, czy jest gotowy, a nie był i był gotowy, ponieważ zapytaliśmy on inny, jeśli był gotowy i on był. Zaczniemy od youyouready Pamiętaj, że w protokole powiedzieliśmy, że może istnieć warunek wyścigu ukryty tam Jedyne co możemy zrobić, to wysłać gotową wiadomość z amready 1 i poradzić sobie z resztą później będziemy musieli czekać znowu, więc nie warto odpowiedzieć na klienta jeszcze W podobny sposób nie wygenerowaliśmy odpowiedzi klientowi, gdy druga strona wysyła notyet do naszego zaproszenia. Z drugiej strony, jeśli drugi jest gotowy, wysyłamy dodatkową gotową wiadomość do innego FSM, odpowiadamy na naszego użytkownika, a następnie przejdźmy do stanu gotowości. Być może zauważyłeś, że używałem acktrans 1 W rzeczywistości oba FSM powinny używać tego Dlaczego to zrozumieć, że mamy to zacząć patrzeć na to, co się dzieje w stanie gotowości. Gdy w stanie gotowości, akcje obu graczy stają się bezużyteczne, z wyjątkiem wycofania Nie wygrałem troski o nowe oferty przedmiotów To daje nam pewną swobodę W zasadzie oba FSM mogą swobodnie rozmawiać ze sobą bez obaw o reszcie świata To pozwala nam na wdrożenie naszego bastardization of a commit dwufazowy Aby rozpocząć to działanie bez żadnego operatora, będziemy potrzebować zdarzenia, aby wywołać akcję z FSM. Zdarzenie ack z acktrans 1 jest używane w tym przypadku Gdy tylko znajdziemy się w stanie gotowości, wiadomość jest traktowany i działał na transakcję może rozpocząć się. Dwufazowe zobowiązanie wymaga komunikacji synchronicznej, choć Oznacza to, że nie możemy mieć obydwu FSM rozpoczęcia transakcji naraz, ponieważ skończą się na punkcie tajnym Sekretem jest znalezienie sposobu, aby zdecydować, że jeden maszyna stanu skończonego powinna zainicjować akcję, podczas gdy druga usiądzie i poczeka na zlecenia od pierwszego. Okazuje się, że inżynierowie i informatycy, którzy zaprojektowali Erlang, byli całkiem sprytni, wiedziałem, że już Pids z jakiegokolwiek procesu mogą być w porównaniu do siebie i posortowane Można to zrobić bez względu na to, czy proces został uruchomiony, czy to jeszcze żyje czy nie, lub jeśli pochodzi z innej maszyny wirtualnej, zobaczymy więcej na ten temat, kiedy dostaniemy się do rozproszonego Erlang. Zauważ, że dwa pids mogą być porównane, a jeden będzie większy od drugiego, możemy napisać priorytet 2 funkcji, który zabierze dwa pids i powiedzie proces, czy został wybrany, czy nie. I wywołując tę ​​funkcję, możemy mieć jeden proces rozpoczynający a następnie następują po zamówieniach. Oto co to daje nam, gdy jest włączony w stanie gotowości, po otrzymaniu wiadomości ack. To duże wyrażenie catch catch to wiodący FSM decydujący o tym, jak działa zatwierdzenie Zarówno askcommit 1, jak i docommit 1 są synchroniczne pozwala wiodącym FSM zadzwonić do nich swobodnie Możesz zobaczyć, że drugi FSM po prostu idzie i czekać To odbierze zamówienia od wiodącego procesu Pierwsza wiadomość powinna być askcommid To jest tylko aby upewnić się, że oba FSMs nadal nie ma nic złego się stało, re poświęcony na wypełnienie zadania. Kiedy się to odbędzie, proces prowadzący poprosi o potwierdzenie transakcji z docommit To kiedy musimy popełnić nasze dane. A kiedy to się skończymy Zostawmy Wiodący FSM otrzyma ok jako odpowiedź i będzie wiedziała, że ​​popełni na swój koniec po tym wszystkim To wyjaśnia, dlaczego potrzebujemy dużej próby przyłapania, jeśli replikacja FSM umiera lub jej odtwarzacz anuluje transakcję, synchroniczne połączenia zostaną zawieszone po upływie limitu czasu Powinno zostać przerwane w tym przypadku. Tak więc wiesz, zdefiniowałem funkcję commit w następujący sposób. Pretty underwhelming, eh Ogólnie nie można zrobić prawdziwego bezpiecznego zobowiązania tylko z dwoma uczestnikami trzecia strona jest zwykle wymagana do oceny, czy obaj gracze zrobili wszystko dobrze Jeśli byłeś aby napisać prawdziwą funkcję commit, powinien skontaktować się z tą stroną trzecią w imieniu obu graczy, a następnie wykonać bezpieczny zapis do bazy danych dla nich lub wycofać całą wymianę. Wygrałoby to wejść w takie szczegóły, a aktualna funkcja commit 1 wystarczająco na potrzeby tej książki. Nie robimy jeszcze Do tej pory nie uwzględniliśmy jeszcze dwóch typów zdarzeń, w których anuluje się handel, a drugi sędzia s skończy się stan maszyny upaść Te pierwsze można rozwiązać przy użyciu callbacks han dleevent 3 i handlesyncevent 4 Kiedy indziej użytkownik zrezygnuje, otrzymamy asynchroniczne powiadomienie. Kiedy to zrobimy, nie wolno nam zapominać, aby powiedzieć drugiemu, zanim się skończymy. I voil Ostatnie zdarzenie, na które należy zwrócić uwagę, to wtedy, gdy inne FSM spada Na szczęście ustawiliśmy monitor w stanie bezczynności. Możemy się z tym zgodzić i odpowiednio reagować. Należy zauważyć, że nawet jeśli zdarzają się anulowanie lub zdarzenia DOWN podczas ponownego zaangażowania, wszystko powinno być bezpieczne i nikt nie powinien kraść jego przedmiotów. Zauważ, że używaliśmy formatu io 2 dla większości naszych wiadomości, aby FSM komunikować się z własnymi klientami W rzeczywistej aplikacji możemy chcieć coś bardziej elastycznego niż ten Jedyny sposób na to pozwala klientowi wysłać Pid, ​​który will receive the notices sent to it That process could be linked to a GUI or any other system to make the player aware of the events The io format 2 solution was chosen for its simplicity we want to focus on the FSM and the asynchronous protocols, not the rest. O nly two callbacks left to cover They re codechange 4 and terminate 3 For now, we don t have anything to do with codechange 4 and only export it so the next version of the FSM can call it when it ll be reloaded Our terminate function is also really short because we didn t handle real resources in this example. We can now try it Well, trying it is a bit annoying because we need two processes to communicate to each other To solve this, I ve written the tests in the file which can run 3 different scenarios The first one is mainab 0 It will run a standard trade and output everything The second one is maincd 0 and will cancel the transaction halfway through The last one is mainef 0 and is very similar to mainab 0 except it contains a different race condition The first and third tests should succeed, while the second one should fail with a crapload of error messages, but that s how it goes You can try it if you feel like it. If you ve found this chapter a bit harder than the others, I must remi nd you that it s entirely normal I ve just gone crazy and decided to make something hard out of the generic finite-state machine behaviour If you feel confused, ask yourself these questions Can you understand how different events are handled depending on the state your process is in Do you understand how you can transition from one state to the other Do you know when to use sendevent 2 and syncsendevent 2-3 as opposed to sendallstateevent 2 and syncsendallstateevent 3 If you answered yes to these questions, you understand what genfsm is about. The rest of it with the asynchronous protocols, delaying replies and carrying the From variable, giving a priority to processes for synchronous calls, bastardized two-phase commits and whatnot are not essential to understand They re mostly there to show what can be done and to highlight the difficulty of writing truly concurrent software, even in a language like Erlang Erlang doesn t excuse you from planning or thinking, and Erlang won t solve you r problems for you It ll only give you tools. That being said, if you understood everything about these points, you can be proud of yourself especially if you had never written concurrent software before You are now starting to really think concurrently. In a real game, there is a lot more stuff going on that could make trading even more complex Items could be worn by the characters and damaged by enemies while they re being traded Maybe items could be moved in and out of the inventory while being exchanged Are the players on the same server If not, how do you synchronise commits to different databases. Our trade system is sane when detached from the reality of any game Before trying to fit it in a game if you dare , make sure everything goes right Test it, test it, and test it again You ll likely find that testing concurrent and parallel code is a complete pain You ll lose hair, friends and a piece of your sanity Even after this, you ll have to know your system is always as strong as its weakest link and thus potentially very fragile nonetheless. Don t Drink Too Much Kool-Aid While the model for this trade system seems sound, subtle concurrency bugs and race conditions can often rear their ugly heads a long time after they were written, and even if they ve been running for years While my code is generally bullet proof yeah, right , you sometimes have to face swords and knives Beware the dormant bugs. Fortunately, we can put all of this madness behind us We ll next see how OTP allows you to handle various events, such as alarms and logs, with the help of the genevent behaviour. Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution Non-Commercial No Derivative License. Porting the AlgoTrader Java code to Erlang to build a high-flexible framework to be used in the following scenarios. Backtest portfolio simulation. Portfolio risk monitoring. Algorithmic trading. Multi-user trading platform server-side. System Integration. This very nic e and well-written project ported to Erlang will be a beautiful case on how you can modulate and scalate to multiple nodes, sharing responsability between processors, in a clean and elegant architecture. You can easily configure nodes to run in separate machines, so the Technical Analysis calculations could be done in other machines, and strategies only subscribes to receive signals. For the first phase of the erlang-trader, the focus is and can t be other to train ourselves on how does a flexible financial message based framework should be , but once we have it running, and more important, people feel that is fun to write strategies on it, we should go deep on the optimization level. The Services I suggest from this begining Every service should be an OTP application. Fix 4 4 Market Data Reader we can do 1 process per instrument. OMS The main order management system, spawn 1 process for every strategy. Strategy Manager Server Every Strategy starts it s own instrument server. Instrument Signa l Server Read the market data from the Fix Adapter and broadcast for subscribed strategies. Portfolio Server Holds Real Time Positions. Sync Server Syncronize porfolio positions with the Broker Positions can be configured to do it every x minutes. Technical Analysis Signals 1 process for every instrument, send signals to the Trade Decision Server. Trade Decision Server receives signals from TA, events, economic reports, etc and send buy sell orders to the OMS. Fix 4 4 Order Server - Translates buy sell signals from the OMS to Fix protocol can be done in FPGA too. R and Matlab plug-in. Let s use the rebar tool to compile and leave this cool things listed below to be done after we have a small working prototype Optimization should be afterwards, let s make it run to see how beautiful an erlang algorithm can trade, and after how fast yeah yeah tons of processes. Since we are using a main file, it s worth to know how it manages dependencies. At Ita Asset Management, we go even further with the FIX Protocol We treat it as an important tool for integration between our internal systems Everyone remembers the traditional conflict between STP and modularity The FIX Protocol standardised and smoothed the path to modularity There is no need for creating and managing interfaces, APIs or even Enterprise Service Buses It is just necessary to include a FIX engine in your application and specify the communication details to every other application via an XML configuration file By Christian J Zimmer and Hellinton Hatsuo Takada, Ita Asset Management.

No comments:

Post a Comment