Monday 25 September 2017

Erlang Trading System


25 Mai 16 00 BST 15 00 UTC 17 00 CET 08 00 PDT Sportrisq ist ein Broker und Distributor von Risikomanagement-Lösungen und Produkten für die Sportbranche Hören Sie CTO Justin Worall beschreiben den Prozess der Migration von zwei Kernplattformkomponenten von Python zu Erlang der Basiswert Probleme, die wahrgenommenen Vorteile von Erlang in diesen Situationen, die Entscheidungsfindung, die Anwendung Designs und die Ergebnisse. In diesem Webinar werden Sie lernen. Der Prozess der Migration von Low-Latency Python-Komponenten zu Erlang. Die Entscheidungsfindung Prozess. Application Entwürfe und Resultate. Learn Sie einige Erlang. Hey dort, es scheint Ihr Javascript ist deaktiviert Das ist gut, die Website funktioniert ohne es Allerdings möchten Sie es lieber mit Syntax Hervorhebung, die Javascript. Rage Against The Finite-State-Maschinen erfordert. Eine Finite-State-Maschine FSM ist nicht wirklich eine Maschine, aber es hat eine endliche Anzahl von Zuständen, die ich immer finite-State-Maschinen gefunden habe, die mit Graphen und Diagrammen einfacher zu verstehen sind. Zum Beispiel wäre das folgende ein vereinfachtes Diagramm für eine sehr dumme Hund als Staatsmaschine. Hier der Hund hat 3 Staaten sitzen, bellen oder wedeln seinen Schwanz Verschiedene Ereignisse oder Eingaben können es zwingen, seinen Zustand zu ändern Wenn ein Hund ruhig sitzt und sieht ein Eichhörnchen, wird es beginnen zu bellen und gewann t zu stoppen bis Du tierst es wieder Aber wenn der Hund sitzt und du es tierst, haben wir keine Ahnung, was passieren könnte In der Erlang-Welt könnte der Hund abstürzen und schließlich von seinem Vorgesetzten neu gestartet werden In der realen Welt wäre das ein freakiges Ereignis, Aber dein Hund würde zurückkommen, nachdem er von einem Auto überfahren worden ist, also ist es nicht alles schlecht. Hier sa Katze s Zustand Diagramm für einen Vergleich. Diese Katze hat einen einzelnen Zustand, und kein Ereignis kann es jemals ändern. Implementing der Katze Zustand Maschine in Erlang ist eine lustige und einfache Aufgabe. Wir können versuchen, das Modul zu sehen, dass die Katze wirklich nie einen Mist. Das gleiche kann für den Hund FSM getan werden, außer mehr Staaten sind available. It sollte relativ einfach zu jedem passen Die Zustände und Übergänge zu dem, was auf dem Diagramm oben ist Hier ist die FSM im Gebrauch. Sie können mit dem Schema folgen, wenn Sie es normalerweise tun möchten, es hilft sicher, dass nichts s falsch ist. Das ist wirklich der Kern der FSMs, die als implementiert werden Erlang-Prozesse Es gibt Dinge, die anders gemacht werden konnten, wir hätten den Status in den Argumenten der Zustandsfunktionen in einer Weise verglichen, die ähnlich dem war, was wir mit der Server-Hauptschleife machen. Wir könnten auch eine init - und beenden-Funktionen hinzugefügt haben, Etc. Ein weiterer Unterschied zwischen dem Hund und der Katze FSMs ist, dass die Katzen-Ereignisse synchron sind und die Ereignisse des Hundes asynchron sind In einer echten FSM könnten beide in einer gemischten Weise verwendet werden, aber ich ging für die einfachste Darstellung aus reinem unerschlossenem Faulheit Es gibt andere Formen des Ereignisses die Beispiele zeigen nicht globale Ereignisse, die in jedem Staat passieren können. Ein Beispiel für ein solches Ereignis könnte sein, wenn der Hund bekommt ein Schnüffeln von Essen Sobald das Geruch Essen Veranstaltung ausgelöst wird, egal was Zustand der Hund ist in, er würde auf der Suche nach der Quelle des Essens suchen. Jetzt haben wir nicht viel zu viel Zeit damit verbringen, das alles in unserer Schriftsprache FSM zu implementieren. Stattdessen bewegen wir uns direkt auf das genfsm-Verhalten. Das Genfsm-Verhalten ist Etwas ähnliches wie Genserver, dass es eine spezialisierte Version von ihm ist Der größte Unterschied ist, dass anstatt Handhabung von Anrufen und Abgüssen wir rehandeln synchrone und asynchrone Ereignisse Viel wie unsere Hunde - und Katzenbeispiele, jeder Staat wird durch eine Funktion wieder dargestellt Gehen Sie durch die Rückrufe, die unsere Module implementieren müssen, um zu arbeiten. Dies ist die gleiche init 1 wie für generische Server verwendet, mit Ausnahme der Rückgabewerte akzeptiert sind und das Stopp-Tupel funktioniert in der gleichen Weise wie für Genserver s und Hibernate und Timeout Behalte die gleiche Semantik. Was ist neu hier ist, dass StateName Variable StateName ist ein Atom und stellt die nächste Callback-Funktion aufgerufen werden. Die Funktionen StateName 2 und StateName 3 sind Platzhalter Namen und Sie sind zu entscheiden, was sie werden Lassen Sie uns annehmen, die Init 1-Funktion gibt das Tupel zurück Das bedeutet, dass die Finite-State-Maschine in einem sitzenden Zustand ist. Dies ist nicht die gleiche Art von Zustand wie wir mit Genserver gesehen haben, ist es eher gleichbedeutend mit der sitzen Rinde und Bachstelze Staaten der vorherigen Hund FSM Diese Staaten Diktieren Sie einen Kontext, in dem Sie ein bestimmtes Ereignis behandeln. Ein Beispiel hierfür wäre jemand, der Sie auf Ihrem Telefon anruft. Wenn Sie in den Zustand schlafen an einem Samstag Morgen, Ihre Reaktion könnte sein, um im Telefon zu schreien Wenn Ihr Staat wartet auf Ein Vorstellungsgespräch, sind die Chancen, dass Sie das Telefon auswählen und höflich antworten. Auf der anderen Seite, wenn Sie in den Zustand tot sind, dann bin ich überrascht, dass Sie diesen Text überhaupt auch lesen können. Zurück zu unserer FSM Die init 1 Funktion sagte wir Sollte im sitzenden Zustand sein Immer wenn der Genfsm-Prozess ein Ereignis erhält, wird entweder die Funktion sitzen 2 oder sitzend 3 wird die Sitzung 2 Funktion ist für asynchrone Ereignisse und sitzen 3 für synchrone diejenigen aufgerufen. Die Argumente für das Sitzen 2 oder allgemein StateName 2 Sind Event die eigentliche Nachricht als ein Ereignis gesendet, und StateData die Daten, die über die Anrufe gesammelt 2 getragen wurde dann können die Tupel und die Argumente für das Sitzen 3 sind ähnlich, außer es ist eine Von Variable zwischen Event und StateData The From Variable wird in genau der gleichen Weise wie es für Genserver s verwendet wurde, einschließlich genfsm Antwort 2 Die StateName 3 Funktionen können die folgenden Tupel zurückgeben. Hinweis, dass es keine Begrenzung, wie viele dieser Funktionen können Sie, solange sie sind Exportiert Die Atome, die als NextStateName in den Tupeln zurückgegeben werden, bestimmen, ob die Funktion aufgerufen wird oder nicht. Im letzten Abschnitt erwähnte ich globale Ereignisse, die eine spezifische Reaktion auslösen würden, egal welcher Zustand wir in den Hund riechenden Essen fallen, was auch immer es ist Tut und wird stattdessen nach Nahrung suchen Für diese Ereignisse, die in jedem Zustand gleich behandelt werden sollten, ist der Handleevent 3 Rückruf, was du willst Die Funktion nimmt Argumente ähnlich wie StateName 2 mit der Ausnahme, dass es eine StateName Variable zwischen ihnen akzeptiert Und erzählte dir, was der Staat war, als das Ereignis empfangen wurde. Es gibt die gleichen Werte wie StateName 2. Die Handlesyncevent 4 Rückruf ist zu StateName 3 was Handleevent 2 ist zu StateName 2 Es behandelt synchrone globale Ereignisse, nimmt die gleichen Parameter und gibt das gleiche zurück Art von Tupeln als StateName 3.Now könnte eine gute Zeit zu erklären, wie wir wissen, ob ein Ereignis ist global oder wenn es s bedeutet, um einen bestimmten Zustand gesendet werden Um dies zu bestimmen, können wir auf die Funktion verwendet, um ein Ereignis zu senden Die FSM-asynchrone Ereignisse, die auf eine beliebige StateName 2-Funktion gerichtet sind, werden mit sendevent 2 synchronen Ereignissen gesendet, die von StateName 3 abgeholt werden sollen, mit syncsendevent 2-3 gesendet werden sollen. Die beiden äquivalenten Funktionen für globale Ereignisse sind sendallstateevent 2 und syncsendallstateevent 2-3 ganz Ein langer name. This funktioniert genau das gleiche wie es für genserver s, außer dass es einen zusätzlichen State-Parameter, wenn aufgerufen wie Codechange OldVersion, StateName, Data, Extra und gibt ein Tupel des Formulars. This sollte wieder ein wenig zu tun Wie das, was wir haben für generische Server beenden 3 sollte das Gegenteil von init 1.It s Zeit, um all dies in der Praxis Viele Erlang Tutorials über Finite-State-Maschinen verwenden Beispiele mit Telefon-Schalter und ähnliche Dinge Es ist meine Vermutung, dass die meisten Programmierer Wird sich selten mit Telefonschaltern für staatliche Maschinen beschäftigen. Aus diesem Grund werden wir ein Beispiel anschauen, das für viele Entwickler passender ist, wir entwerfen und implementieren ein Artikelhandelssystem für ein fiktives und nicht existierendes Videospiel Design, das ich ausgewählt habe, ist etwas anspruchsvoll Anstatt einen Makler zu benutzen, durch den Spieler Gegenstände und Bestätigungen abgeben, die ehrlich gesagt einfacher werden, werden wir einen Server implementieren, bei dem beide Spieler direkt miteinander sprechen, was den Vorteil haben würde, verteilbar zu sein. Wenn die Implementierung schwierig ist, verbringe ich eine gute, während ich sie beschreibe, die Art von Problemen, um konfrontiert zu werden und die Möglichkeiten, sie zu beheben. Zunächst sollten wir die Aktionen definieren, die von unseren Spielern beim Handel durchgeführt werden können Fordert, dass ein Handel eingerichtet wird Der andere Benutzer sollte auch in der Lage sein, diesen Handel zu akzeptieren Wir haben t geben ihnen das Recht, einen Handel zu verweigern, obwohl, weil wir die Dinge einfach halten wollen. Es wird einfach sein, diese Funktion einmal hinzuzufügen Die ganze Sache ist getan. Wenn der Handel eingerichtet ist, sollten unsere Benutzer in der Lage sein, miteinander zu verhandeln Das bedeutet, dass sie in der Lage sein sollten, Angebote zu machen und dann zurückzuziehen, wenn sie wollen Wenn beide Spieler mit dem Angebot zufrieden sind, können sie Jeder deklariert sich als bereit, den Handel abzuschließen. Die Daten sollten dann irgendwo auf beiden Seiten gespeichert werden. Zu irgendeinem Zeitpunkt sollte es auch sinnvoll sein, dass irgendwelche Spieler den ganzen Handel abbrechen können. Ein Pleb könnte nur Gegenstände anbieten, die für unwürdig gehalten wurden Die andere Partei, die sehr beschäftigt sein könnte und so sollte es möglich sein, sie mit einer wohlverdienten Kündigung zurückzugeben. Kurz gesagt, die folgenden Aktionen sollten möglich sein. Für einen Trade. accept ein trade. offer items. retract ein Angebot. Erklären Sie sich selbst als ready. brutally kündigen Sie den Handel. Jetzt, wenn jede dieser Aktionen getroffen wird, sollte die andere Spieler s FSM bewusst gemacht werden Dies ist sinnvoll, denn wenn Jim seine FSM sagt, um ein Element an Carl, Carl s zu senden FSM muss darauf aufmerksam gemacht werden Das bedeutet, dass beide Spieler mit ihrer eigenen FSM sprechen können, die mit dem anderen FSM sprechen wird. Das gibt uns etwas ein bisschen wie das. Das erste, was zu beachten ist, wenn wir zwei identische Prozesse haben, die mit jedem kommunizieren Andere ist, dass wir synchrone Anrufe so weit wie möglich vermeiden müssen Der Grund dafür ist, dass wenn Jims FSM eine Nachricht an Carls FSM sendet und dann auf seine Antwort wartet, während gleichzeitig Carls FSM eine Nachricht an Jim sendet S FSM und wartet auf seine eigene spezifische Antwort, beide am Ende wartet auf den anderen, ohne jemals zu antworten Dies behebt effektiv beide FSMs Wir haben einen Deadlock. Eine Lösung dafür ist, auf ein Timeout zu warten und dann weiter zu gehen, aber dann wird es sein Übrig gebliebene Meldungen in beiden Prozessen Postfächer und das Protokoll wird verwirrt werden Dies ist sicherlich eine Dose Würmer, und so wollen wir es vermeiden. Der einfachste Weg, um es zu tun ist, um alle synchronen Nachrichten zu vermeiden und gehen vollständig asynchron Hinweis, dass Jim könnte noch Machen einen synchronen Anruf zu seinem eigenen FSM dort s kein Risiko hier, weil die FSM gewann t müssen Jim anrufen und so kein Deadlock zwischen ihnen auftreten können. Wenn zwei dieser FSMs kommunizieren zusammen, könnte die ganze Börse ein bisschen wie dies aussehen FSMs sind in einem untätigen Zustand Wenn du Jim zum Handel fragst, muss Jim akzeptieren, bevor die Dinge weitergehen Dann können beide von euch Gegenstände anbieten oder sie zurückziehen Wenn ihr euch beide bereit erklärt habt, kann der Handel stattfinden. Dies ist eine vereinfachte Version von Alles, was passieren kann, und wir sehen alle möglichen Fälle mit mehr Details in den nächsten Absätzen. Hier kommt der harte Teil, der das Zustandsdiagramm definiert und wie die Zustandsübergänge geschehen. Normalerweise geht ein gutes Denken in dieses, weil man an alle denken muss Die kleinen Dinge, die schief gehen könnten Einige Dinge könnten schief gehen, auch nachdem sie es schon oft überprüft haben. Darum lasse ich einfach das, was ich beschlossen habe, hier zu implementieren und es dann zu erklären. Zuerst beginnen beide Finite-State-Maschinen in der Leerlauf-Zustand An diesem Punkt ist eine Sache, die wir tun können, ist, einen anderen Spieler zu bitten, mit uns zu verhandeln. Wir gehen in den idlewait-Modus, um auf eine eventuelle Antwort zu warten, nachdem unsere FSM die Nachfrage weitergeleitet hat. Sobald die andere FSM die Antwort sendet, können unsere Um zu verhandeln. Der andere Spieler sollte auch verhandeln Zustand nach diesem Offensichtlich, wenn wir können die anderen einladen, kann der andere uns einladen Wenn alles gut geht, sollte dies am Ende aussehen wie this. So das ist so ziemlich das Gegenteil wie Die beiden vorherigen staatlichen Diagramme, die in eine Anmerkung gebündelt werden, dass wir erwarten, dass der Spieler das Angebot in diesem Fall akzeptiert Was passiert, wenn durch reines Glück, bitten wir den anderen Spieler, mit uns zu handeln, während er uns bittet, zu handeln. Was passiert hier Ist, dass beide Kunden ihre eigene FSM fragen, um mit dem anderen zu verhandeln Sobald die Fragen verhandeln Nachrichten gesendet werden, wechseln beide FSMs in den idlewait Zustand Dann werden sie in der Lage sein, die Verhandlungsfrage zu verarbeiten Wenn wir die vorherigen Zustandsdiagramme überprüfen, sehen wir Dass diese Kombination von Ereignissen die einzige Zeit ist, in der wir die Verhandlungsmeldungen erhalten, während wir uns im idlewait-Zustand verständigen. Daher wissen wir, dass diese Nachrichten in idlewait bedeutet, dass wir die Rennbedingung treffen und davon ausgehen können, dass beide Benutzer miteinander reden wollen Bewegen Sie beide von ihnen zu verhandeln Staat Hooray. So jetzt wir verhandeln Entsprechend der Liste der Aktionen, die ich früher aufgeführt habe, müssen wir Benutzer unterstützen, die Gegenstände anbieten und dann das Angebot zurückziehen. Alle dies ist vorwärts unsere Client-Nachricht an die andere FSM Beide Finite-State-Maschinen müssen eine Liste von Artikeln, die von jedem Spieler angeboten werden, halten, so dass sie diese Liste aktualisieren können, wenn sie solche Nachrichten erhalten. Wir bleiben im Verhandlungszustand, nachdem dieser vielleicht der andere Spieler auch Gegenstände anbieten will. Hier ist unsere FSM grundsätzlich Wirkt auf eine ähnliche Art und Weise Dies ist normal Sobald wir müde sind, Dinge anzubieten und zu denken, dass wir großzügig genug sind, müssen wir sagen, dass wir bereit sind, den Handel zu beenden Da wir beide Spieler synchronisieren müssen, müssen wir einen Zwischenzustand verwenden, Wie wir es für Leerlauf und Idlewait getan haben. Was wir hier machen, ist, dass, sobald unser Spieler fertig ist, unsere FSM Jims FSM fragt, ob er bereit ist. Angesichts seiner Antwort fällt unsere eigene FSM in ihren Wartezustand Die Antwort, die wir bekommen werden wird Hängt von Jims FSM-Zustand ab, wenn es im Wartezustand ist, es wird uns sagen, dass es fertig ist Andernfalls wird es uns sagen, dass es noch nicht fertig ist Das ist genau das, was unsere FSM automatisch auf Jim antwortet, wenn er uns fragt, ob wir sind Bereit, wenn in verhandeln state. Our Finite-State-Maschine wird in Verhandlungs-Modus bleiben, bis unser Spieler sagt, er ist bereit Let s davon ausgehen, er tat und wir sind jetzt in der Warte-Zustand Allerdings Jim ist noch nicht da Dies bedeutet, dass, wenn wir uns als erklären Fertig, wir haben Jim gefragt, ob er auch fertig war und seine FSM wird noch nicht geantwortet haben. Er ist nicht bereit, aber wir sind Wir können viel tun, aber warten auf Warten auf Jim, die immer noch verhandeln, Es ist möglich, dass er versuchen wird, uns mehr Gegenstände zu schicken oder vielleicht seine vorherigen Angebote zu stornieren. Natürlich wollen wir Jim vermeiden, alle seine Gegenstände zu entfernen und dann auf mich zu klicken, und ich schaue mich in den Prozess. Sobald er sich ändert Die angebotenen Gegenstände, gehen wir wieder in den Verhandlungszustand, so dass wir entweder unser eigenes Angebot modifizieren oder das aktuelle zu prüfen und zu entscheiden, dass wir fertig sind Spülen und wiederholen. Irgendwann wird Jim bereit sein, den Handel zu beenden, wenn dies geschieht , Wird seine Finite-State-Maschine fragen, ob wir bereit sind. Was unsere FSM ist, antwortet, dass wir in der Tat bereit sind Wir bleiben im Wartezustand und weigern uns, in den fertigen Zustand zu bewegen Warum ist das Da gibt es eine mögliche Race-Bedingung Stellen Sie sich vor Dass die folgende Abfolge von Ereignissen stattfindet, ohne diesen notwendigen Schritt zu tun. Dies ist ein bisschen komplex, so dass ich es erklären werde Wegen der Art und Weise, wie Nachrichten empfangen werden, könnten wir das Itemangebot nur verarbeiten, nachdem wir uns bereit und auch nach Jim erklärt haben Erklärte sich als bereit Dies bedeutet, dass, sobald wir die Angebotsnachricht lesen, wir zurückkehren, um den Zustand zu verhandeln. Während dieser Zeit wird Jim uns erzählt haben, dass er bereit ist, wenn er dort die Staaten wechseln und wie oben beschrieben fertig werden soll , Er würde gefangen warten auf unbestimmte Zeit, während wir nicht wissen, was zum Teufel zu tun Dies könnte auch passieren, die andere Weise um Ugh. One Weg, um dies zu lösen ist durch Hinzufügen einer Schicht von indirection Dank David Wheeler Dies ist, warum wir warten auf warten Modus und senden Sie bereit, wie in unserem vorherigen Zustand Diagramm gezeigt Hier s, wie wir mit dieser bereit Nachricht, vorausgesetzt, wir waren bereits in den bereiten Zustand, weil wir unsere FSM waren wir vorher bereit waren. Wenn wir von der anderen FSM bereit sind, senden wir Bereit wieder zurück Dies ist, um sicherzustellen, dass wir gewann t haben die doppelte Race Bedingung oben erwähnt Dies wird eine überflüssige bereit Nachricht in einem der beiden FSMs zu schaffen, aber wir müssen nur ignorieren es in diesem Fall Wir senden dann eine Ack-Nachricht Und die Jim s FSM wird das gleiche tun, bevor sie in den bereiten Zustand Der Grund, warum diese ack Nachricht existiert ist aufgrund einiger Implementierung Details über die Synchronisierung von Clients Ich habe es in das Diagramm für das Sein richtig, aber ich gewann t erklären es Bis später Vergessen Sie es für jetzt Wir haben es endlich geschafft, beide Spieler zu synchronisieren Whew. So jetzt da ist der fertige Zustand Dies ist ein bisschen Besonderes Beide Spieler sind bereit und haben grundsätzlich den Finite-State-Maschinen die ganze Kontrolle gegeben, die sie brauchen. Das lässt uns Implementieren eine bastardisierte Version eines Zwei-Phasen-Commit, um sicherzustellen, dass die Dinge richtig gehen, wenn die Handels-offiziellen. Unsere Version wie oben beschrieben wird ziemlich einfach sein Schreiben ein wirklich korrektes Zwei-Phasen-Commit würde viel mehr Code als das, was notwendig ist Uns zu verstehen, Finite-State-Maschinen. Schließlich müssen wir nur erlauben, dass der Handel zu jeder Zeit abgesagt werden Dies bedeutet, dass irgendwie, egal in welchem ​​Zustand wir re in, wir gehen, um die Abbruch-Nachricht von beiden Seiten zu hören und zu beenden Die Transaktion Es sollte auch gemeinsame Höflichkeit sein, um die andere Seite wissen, dass wir vergangen sind, bevor wir gehen. Alright Es sa eine ganze Menge von Informationen zu absorbieren auf einmal Don t Sorge, wenn es eine Weile dauert, um es vollständig zu erfassen Es hat eine Menge Leute zu Schauen Sie über mein Protokoll, um zu sehen, ob es richtig war, und selbst dann haben wir alle ein paar Rennbedingungen verpasst, die ich dann ein paar Tage später erwischt habe, als ich den Code beim Schreiben dieses Textes kenne. Es ist normal, dass er es mehr als einmal lesen muss Wenn Sie nicht an asynchrone Protokolle gewöhnt sind Wenn dies der Fall ist, ich ermutige Sie vollkommen, um zu versuchen, Ihr eigenes Protokoll zu entwerfen Dann fragen Sie sich, was passiert, wenn zwei Leute die gleichen Aktionen sehr schnell tun Was, wenn sie zwei andere Ereignisse schnell ketten Was habe ich Tun mit Mitteilungen, die ich nicht behandeln werde, wenn ich die Zustände ändere. Sie werden sehen, dass die Komplexität wirklich schnell wächst Sie könnten eine Lösung finden, die meiner ähnlich ist, möglicherweise ein besserer, lassen Sie mich wissen, wenn dies der Fall ist Egal das Ergebnis, es ist eine sehr interessante Sache Um zu arbeiten und unsere FSMs sind immer noch relativ einfach. Wenn Sie das alles ganz oder gar verdaut haben, wenn Sie ein Rebell Leser sind, können Sie zum nächsten Abschnitt gehen, wo wir das Spielsystem implementieren. Jetzt können Sie einen schönen Kaffee nehmen Pause, wenn du Lust hast, dies zu tun. Das erste, was getan werden muss, um unser Protokoll mit OTP s genfsm zu implementieren, besteht darin, die Schnittstelle zu schaffen. Es werden 3 Anrufer für unser Modul der Spieler, das Genfsm Verhalten und der andere Spieler s FSM We Muss nur die Spieler-Funktion und genfsm-Funktionen zu exportieren, obwohl dies ist, weil die anderen FSM wird auch innerhalb der tradefsm-Modul laufen und können sie von innen zugreifen. So, dass s unsere API Sie können sehen, ich bin auf einige Funktionen zu planen Sowohl synchron als auch asynchron Dies ist vor allem, weil wir möchten, dass unser Kunde uns in einigen Fällen synchron anruft, aber der andere FSM kann es asynchron machen. Der Client synchronisiert die Logik eine ganze Menge durch die Begrenzung der Anzahl der widersprüchlichen Nachrichten, die man senden kann Nach dem anderen werden wir dorthin gelangen Lassen Sie uns zuerst die eigentliche öffentliche API nach dem oben definierten Protokoll implementieren. Dies ist eher Standard alle diese Genfm-Funktionen wurden abgedeckt, außer außer 3-4 und Startlink 3-4, die ich glaube, dass Sie sich bezeichnen können Out in diesem Kapitel. Next wir ll implementieren die FSM zu FSM-Funktionen Die ersten haben mit Handels-Setups zu tun, wenn wir zuerst wollen, dass der andere Benutzer, um uns in einem Handel zu besuchen. Die erste Funktion fragt die andere pid, wenn sie wollen Zu handeln, und die zweite wird verwendet, um es asynchron zu beantworten, natürlich. Wir können dann schreiben die Funktionen zu bieten und stornieren Angebote Nach unserem Protokoll oben, das ist, was sie sein sollten. So, jetzt, wo wir haben Diese Anrufe getan haben, müssen wir uns auf den Rest konzentrieren Die verbleibenden Anrufe beziehen sich darauf, fertig zu sein oder nicht und die Abwicklung der endgültigen Verpflichtung Wieder, da unser Protokoll oben, haben wir drei Anrufe sind bereits, die die Antworten notyet oder ready. The nur Funktionen links haben können Sind diejenigen, die von beiden FSMs verwendet werden sollen, wenn sie das Commit im fertigen Zustand machen. Ihre genaue Verwendung wird später ausführlicher beschrieben, aber jetzt müssen die Namen und das Sequenzstatusdiagramm von früher genug sein. Trotzdem können Sie noch Transkribieren sie zu deiner eigenen Version von tradefsm. Oh und da s auch die Höflichkeitsfunktion, die uns erlaubt, die andere FSM zu warnen, die wir den Handel abgesagt haben. Wir können jetzt zu dem wirklich interessanten Teil die genfsm Rückrufe bewegen Der erste Rückruf ist init 1 In unserem Fall , Wir wollen, dass jeder FSM einen Namen für den Benutzer hat, den er so repräsentiert, unsere Ausgabe wird netter sein in den Daten, die er an sich weitergibt. Was sonst wollen wir in Erinnerung halten In unserem Fall wollen wir die anderen s Pid, die Artikel, die wir anbieten und die Gegenstände die anderen Angebote Wir werden auch die Referenz eines Monitors hinzufügen, so dass wir wissen, abzubrechen, wenn die anderen stirbt und ein aus Feld, verwendet, um verzögerte Antworten zu tun. Im Falle von init 1 wir Ich kümmere mich nur um unseren Namen für jetzt. Beachten Sie, dass wir im Ruhezustand beginnen. Die nächsten Rückrufe, die zu berücksichtigen sind, sind die Staaten selbst. Bisher habe ich die Zustandsübergänge und Anrufe beschrieben, die gemacht werden können, aber wir brauchen einen Weg zu Stellen Sie sicher, dass alles in Ordnung ist Wir werden ein paar Utility-Funktionen erstmal schreiben. Und wir können mit dem Leerlauf-Zustand beginnen. Um der Konvention zu begegnen, decke ich die asynchrone Version zuerst. Das muss man sich nicht um etwas kümmern, aber der andere Spieler fragt nach Ein Handel, der unserem eigenen Spieler gegeben wird, wenn man sich die API-Funktionen anschaut, wird ein synchroner Anruf verwendet. Ein Monitor ist so eingerichtet, dass er das andere Sterben verarbeiten kann, und sein Ref wird in den FSM-Daten zusammen mit den anderen s gespeichert Pid, bevor du in den idlewait-Zustand gehst. Beachten wir, dass wir alle unerwarteten Ereignisse melden und sie ignorieren werden, indem wir in dem Zustand bleiben, in dem wir bereits waren. Wir können ein paar Out-of-Band-Nachrichten hier und da haben, die das Ergebnis von Rennbedingungen sein könnte In der Regel sicher zu ignorieren sie, aber wir können nicht leicht loszuwerden sie Es ist einfach besser, nicht zu brechen die ganze FSM auf diese unbekannten, aber etwas erwartete Nachrichten. Wenn unser eigener Client fragt die FSM an einen anderen Spieler für einen Handel zu kontaktieren, es Wird ein synchrones Ereignis senden Der Leerlauf 3 Rückruf wird benötigt. Wir gehen in einer ähnlichen Weise wie die asynchrone Version, außer wir müssen tatsächlich die andere Seite fragen, ob sie mit uns verhandeln wollen oder nicht Sie werden feststellen, dass wir nicht antworten An den Klienten noch Das ist, weil wir nichts Interessantes zu sagen haben, und wir wollen, dass der Klient gesperrt ist und darauf wartet, dass der Handel akzeptiert wird, bevor er etwas tut. Die Antwort wird nur gesendet, wenn die andere Seite akzeptiert wird, sobald wir in idlewait. Wenn wir sind Da müssen wir uns mit dem anderen befassen, der akzeptiert wird, zu verhandeln, und der andere bittet, das Ergebnis einer Rennbedingung zu verhandeln, wie es in dem Protokoll beschrieben ist. Dies gibt uns zwei Übergänge in den Verhandlungszustand, aber denken Sie daran, dass wir die genfsm Antwort verwenden müssen 2 antworte auf unseren kunden, um es zu sagen, es ist okay, anzufangen, Gegenstände anzufertigen Es gibt auch den Fall unseres FSM-Klienten, der den Handel akzeptiert, der von der anderen Partei vorgeschlagen wird. Hier geht es weiter zum Verhandlungszustand Hier müssen wir asynchron behandeln Abfragen zum Hinzufügen und Entfernen von Gegenständen, die sowohl vom Client als auch von der anderen FSM kommen. Allerdings haben wir uns noch nicht entschieden, wie man Gegenstände speichert. Weil ich etwas faul bin und ich davon ausgehen, dass die Benutzer gewann t Handel, dass viele Artikel, einfache Listen wird es für jetzt tun , Könnten wir unseren Verstand zu einem späteren Zeitpunkt ändern, also wäre es eine gute Idee, Einzelteiloperationen in ihren eigenen Funktionen einzuwickeln Fügen Sie die folgenden Funktionen am unteren Rand der Akte mit Anmerkung 3 und unerwartetes 2.Simple hinzu, aber sie haben die Rolle Der Isolierung der Aktionen Hinzufügen und Entfernen von Elementen aus ihrer Umsetzung mit Listen Wir konnten leicht auf Proplisten, Arrays oder was auch immer Datenstruktur ohne Unterbrechung der Rest des Codes zu bewegen. Unter dieser beiden Funktionen können wir das Angebot und das Entfernen von Gegenständen zu implementieren. Dies ist ein Hässlicher Aspekt der Verwendung von asynchronen Nachrichten auf beiden Seiten Ein Satz von Nachrichten hat die Form zu machen und zurückzuziehen, während die andere hat und rückgängig Dies ist völlig willkürlich und nur verwendet, um zwischen Spieler-zu-FSM-Kommunikation und FSM-zu-FSM-Kommunikation zu unterscheiden Beachten Sie, dass bei denjenigen, die von unserem eigenen Spieler kommen, müssen wir die andere Seite über die Änderungen, die wir wieder machen zu erzählen. Eine andere Verantwortung ist, um die areyouready Nachricht zu behandeln, die wir im Protokoll erwähnt haben Dies ist das letzte asynchrone Ereignis, das im Verhandlungszustand zu behandeln ist. Sie, die im Protokoll beschrieben werden, wann immer wir nicht in den Wartezustand sind und diese Nachricht erhalten, müssen wir mit notyet antworten. Wurden auch Einzelhandelsdetails an den Benutzer ausgegeben, so dass eine Entscheidung getroffen werden kann. Wenn eine solche Entscheidung getroffen wird und der Benutzer ist Fertig, das fertige Ereignis wird gesendet werden Dies sollte synchron sein, weil wir nicht wollen, dass der Benutzer sein Angebot beibehalten wird, indem er Gegenstände hinzufügt, während er behauptet, dass er bereit ist. An diesem Punkt sollte ein Übergang zum Wartezustand gemacht werden Für die anderen ist nicht interessant Wir speichern die Von-Variable, so können wir es mit genfsm Antwort 2 verwenden, wenn wir etwas haben, um den Client zu sagen. Der Wartezustand ist ein lustiges Biest Neue Artikel könnten angeboten und zurückgezogen werden, weil der andere Benutzer nicht Sei bereit Es ist also sinnvoll, automatisch zum Verhandlungszustand zurückzukehren. Es würde saugen, dass wir uns tolle Gegenstände bieten, nur für die anderen, um sie zu entfernen und sich bereit zu erklären, unsere Beute zu stehlen. Zurück zur Verhandlung ist eine gute Entscheidung. Nun, das ist etwas Sinnvolles und wir antworten auf den Spieler mit den Koordinaten, die wir gespeichert haben. Der nächste Satz von Nachrichten, die wir uns Sorgen machen müssen, sind diejenigen, die mit der Synchronisation von beiden FSMs zusammenhängen, damit sie in den Bereitschaftszustand wechseln und den Handel bestätigen können Wir sollten uns wirklich auf das zuvor definierte Protokoll konzentrieren. Die drei Nachrichten, die wir haben könnten, sind schon, weil der andere Benutzer sich gerade bereit erklärt hat, denn wir haben den anderen gefragt, ob er bereit war und er war nicht und bereit, weil wir den anderen gefragt haben, ob er War fertig und er war. Wir beginnen mit isyouready Denken Sie daran, dass in dem Protokoll haben wir gesagt, dass es eine Race-Zustand versteckt werden könnte Das einzige, was wir tun können, ist die fertige Nachricht mit bereits 1 und befassen sich mit dem Rest später. Wir ll Bleibe schon wieder warten, also lohnt es sich nicht, auf unseren Klienten zu antworten. Ähnlich haben wir t Antwort auf den Klienten, wenn die andere Seite einen Notyet zu unserer Einladung sendet. Auf der anderen Seite, wenn der andere fertig ist, senden wir eine extra Fertige Nachricht an die andere FSM, antworte auf unseren eigenen Benutzer und gehe dann in den fertigen Zustand. Du hättest vielleicht bemerkt, dass ich acktrans verwendet habe. In der Tat sollten beide FSMs es benutzen Warum ist dies zu verstehen, dass wir anfangen müssen zu betrachten Was im fertigen Zustand vor sich geht. Wenn im Bereitschaftszustand, werden beide Spieler Aktionen nutzlos, außer Annullierung Wir haben uns um neue Artikelangebote gekümmert Dies gibt uns etwas Freiheit Grundsätzlich können beide FSMs frei miteinander reden, ohne sich um den Rest zu kümmern Die Welt Damit können wir unsere Bastardisierung eines zweiphasigen Commits umsetzen, um diese Begegnung ohne Spielerspiel zu beginnen, wir brauchen ein Event, um eine Aktion aus den FSMs auszulösen. Das Ack Event von acktrans 1 wird dafür verwendet. Sobald wir re Im fertigen Zustand, die Nachricht behandelt und gehandelt auf die Transaktion kann beginnen. Zwei-Phasen-Commits erfordern synchrone Kommunikation, aber das bedeutet, wir können t haben beide FSMs starten die Transaktion auf einmal, weil sie ll am Ende verriegelt Das Geheimnis ist Finden Sie einen Weg zu entscheiden, dass eine Finite-State-Maschine sollte das Commit zu initiieren, während die anderen sitzen und warten auf Aufträge von der ersten. Es stellt sich heraus, dass die Ingenieure und Informatiker, die Erlang entworfen waren ziemlich klug gut, wir wussten, dass bereits Die Pids eines jeden Prozesses können miteinander verglichen und sortiert werden. Dies kann getan werden, egal, wann der Prozess hervorgebracht wurde, ob es noch am Leben ist oder nicht, oder wenn es von einer anderen VM kommt, werden wir mehr darüber sehen, wenn wir hineinkommen Verteilt Erlang. Knowing, dass zwei pids verglichen werden können und man wird größer als die anderen, können wir schreiben eine Funktion Priorität 2, die zwei pids nehmen und einen Prozess, ob es s gewählt wurde oder nicht. Und durch den Aufruf dieser Funktion, wir Kann ein Prozess, der das Commit beginnt, und das andere, das den Befehlen folgt. Hier ist das, was uns das gibt, wenn es in den fertigen Zustand aufgenommen wird. Nach dem Erhalt der ack message. This großen try catch expression ist die führende FSM entscheiden, wie die Commit bearbeitet Beide askcommit 1 Und docommit 1 sind synchronen Dies lässt die führende FSM sie frei nennen Sie können sehen, dass die andere FSM nur geht und warten Sie erhalten dann die Aufträge aus dem führenden Prozess Die erste Nachricht sollte askcommit Dies ist nur um sicherzustellen, dass beide FSMs noch sind Da ist nichts falsch passiert, sie sind beide gewidmet, um die Aufgabe zu vervollständigen. Wenn dies empfangen wird, wird der führende Prozess bitten, die Transaktion mit docommit zu bestätigen. Das ist, wenn wir unsere Daten verpflichten müssen. Und sobald es fertig ist, verlassen wir die führende FSM Wird als Antwort antworten und wird wissen, dass sie sich nach eigenem Ende verpflichten wird. Dies erklärt, warum wir den großen Versuch brauchen, wenn der antwortende FSM stirbt oder sein Spieler die Transaktion abbricht, werden die synchronen Anrufe nach einem Timeout abstürzen. Das Commit sollte abgebrochen werden In diesem Fall. Just so Sie wissen, habe ich die Commit-Funktion wie folgt definiert. Pretty underwhelming, eh Es ist in der Regel nicht möglich, eine echte sichere verpflichten mit nur zwei Teilnehmer ein Dritter ist in der Regel erforderlich, um zu beurteilen, ob beide Spieler alles richtig gemacht haben Wenn du eine echte Commit-Funktion schreiben würdest, dann solltest du diesen Dritten im Namen der beiden Spieler kontaktieren und dann den Safe in eine Datenbank schreiben oder die ganze Börse zurückschleppen. Wir haben in diese Details gegangen und das aktuelle Commit 1 Funktion wird genug für die Bedürfnisse dieses Buches sein. Wir sind noch nicht fertig Wir haben noch nicht zwei Arten von Ereignissen abgedeckt, die ein Spieler, der den Handel annulliert, und der andere Spieler, der Finite-State-Maschine stürzt. Der ehemalige kann mit den Callbacks Handleevent behandelt werden 3 und handlesyncevent 4 Immer wenn der andere User abbricht, werden wir eine asynchrone Benachrichtigung erhalten. Wenn wir es tun, dürfen wir nicht vergessen, den anderen zu erzählen, bevor wir uns beenden. Und voil Das letzte Ereignis, das darauf achtet, ist, wenn die andere FSM untergeht , Hatten wir einen Monitor zurück in den Ruhezustand gesetzt Wir können darauf passen und entsprechend reagieren. Hinweis, dass auch wenn die Abbruch oder DOWN Ereignisse passieren, während wir in der Commit, alles sollte sicher sein und niemand sollte seine Artikel gestohlen bekommen. Hinweis Wir haben io Format 2 für die meisten unserer Nachrichten verwendet, um die FSMs mit ihren eigenen Klienten zu kommunizieren In einer realen Weltanwendung möchten wir vielleicht etwas flexibleres als das eine Möglichkeit, es zu tun, ist, den Klienten in ein Pid zu schicken, das wird 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. Only 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 remind 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 your 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 nice 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 Signal 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