Tuesday 26 September 2017

Erlang Trading System


25 maj 16 00 BST 15 00 UTC 17 00 CET 08 00 PDT Sportrisq är en mäklare och distributör av riskhanteringslösningar och produkter till sportbranschen Lyssna på CTO Justin Worall beskriver processen att migrera två kärnplattformskomponenter från Python till Erlang underliggande Problem som berörs, upplevda fördelar med Erlang i de situationerna, beslutsprocessen, applikationsdesignerna och resultaten. I det här webinaret lär du dig. Processen att migrera low-latency Python-komponenter till Erlang. Decision making process. Application Design och results. Learn you some Erlang. Hey där, det verkar att Javascript är inaktiverat Det är bra, webbplatsen fungerar utan det. Du kanske föredrar att läsa den med syntaxmarkering, vilket kräver Javascript. Rage Against The Finite State Machines. En finit-state-maskin FSM är inte riktigt en maskin, men den har ett begränsat antal stater. Jag har alltid funnit finite-state-maskiner som är enklare att förstå med diagram och diagram. Exempelvis skulle följande vara ett förenklat schema för en mycket dum hund som en statlig maskin. Hästen har 3 stater som sitter, skäller eller svävar sin svans. Olika händelser eller ingångar kan tvinga det att ändra sitt tillstånd. Om en hund sitter lugnt och Ser en ekorre, det börjar börja skälla och vinner t stoppa tills du husdjur det igen Men om hunden sitter och du husdjur det, har vi ingen aning om vad som kan hända. I Erlang-världen kan hunden krascha och så småningom startas om av Sin handledare i den verkliga världen som skulle vara en freaky händelse, men din hund skulle komma tillbaka efter att ha sprang över av en bil, så det är inte så illa. Här är kattens statliga diagram för en jämförelse. Denna katt har ett enda tillstånd , Och ingen händelse kan någonsin ändra den. Genomförandet av katttillståndsmaskinen i Erlang är en rolig och enkel uppgift. Vi kan prova modulen för att se att katten verkligen aldrig ger skit. Detsamma kan göras för hunden FSM utom mer Tillstånd är tillgängliga. Det ska vara relativt enkelt att matcha varje stat och tr Ansökningar till vad som var på diagrammet ovan Här är FSM i bruk. Du kan följa med schemat om du vill att jag brukar göra det, det hjälper till att vara säker på att ingenting är fel. Det är verkligen kärnan i FSMs implementerade som Erlang processer där Är saker som kunde ha gjorts annorlunda, vi kunde ha passerat staten i argumenten för de statliga funktionerna på ett sätt som liknar vad vi gör med servrarna. Vi kan också ha lagt till init och avsluta funktioner, hanterade koduppdateringar etc. Another Skillnaden mellan hund och katt FSMs är att kattens händelser är synkrona och hundens händelser är asynkrona. I en riktig FSM kan båda användas på ett blandat sätt, men jag gick för den enklaste representationen ur ren oanvänd lata. Det finns Andra former av händelse exemplen visar inte globala händelser som kan hända i någon stat. Ett exempel på en sådan händelse kan vara när hunden får en sniff av mat När luktens mathändelse utlöses, oavsett vilket tillstånd hunden är i Han går Letar efter källan till mat. Nu vann vi inte tillbringa för mycket tid på att implementera allt detta i vår skrivna-på-servett FSM. I stället kommer vi att flytta direkt till genfsm-beteendet. Genfsm-beteendet liknar genserver Är en specialiserad version av den. Den största skillnaden är att istället för att hantera samtal och kasta vi hanterar synkrona och asynkrona händelser. Mycket som våra hund - och kattexemplar representeras varje stat av en funktion. Återigen går vi igenom de återkallningar våra moduler behöver Att implementera för att fungera. Det här är samma init 1 som används för generiska servrar, förutom att de returnerade värdena är accepterade och Stop-tupeln fungerar på samma sätt som för genserver s och viloläge och Timeout behåll samma semantik. Vad s Nytt här är den statliga variabla StateName är en atom och representerar nästa återuppringningsfunktion som ska kallas. Funktionerna StateName 2 och StateName 3 är platshållarens namn och du ska bestämma vad de ska bli. Låt oss anta init 1 Funktionen returnerar tupeln Det betyder att den ändliga tillståndsmaskinen kommer att vara i sittande tillstånd Detta är inte samma typ av tillstånd som vi hade sett med genserver det är ganska ekvivalent med sitta bark och wagtail tillstånd av föregående hund FSM Dessa stater dikterar en Kontext där du hanterar en given händelse. Ett exempel på detta skulle vara någon som ringer dig på din telefon. Om du är i staten som sover på en lördagsmorgon kan din reaktion vara att skrika i telefonen Om ditt tillstånd väntar på ett jobb Intervju, chansen är att du ska välja telefonen och svara artigt. Om du är i staten död, är jag förvånad över att du även kan läsa den här texten alls. Bakom vår sms Den init 1-funktionen sa att vi borde vara I sittande tillstånd När genfsm-processen tar emot en händelse, kommer funktionen sittande 2 eller sittande 3 att ringas. Funktionen Sitting 2 kallas för asynkrona händelser och sitter 3 för synkrona. Argumenten för sittande 2 eller allmänt StateName 2 är Händelse det faktiska meddelandet skickat som en händelse och StateData de data som överfördes via samtalen sitter 2 kan sedan returnera tuplarna och. Argumenten för sittande 3 är lika, förutom att det finns en Från-variabel mellan Event och StateData The From-variabeln Används på exakt samma sätt som det var för genserver s, inklusive genfsm svar 2 StateName 3-funktionerna kan returnera följande tuples. Note att det finns ingen gräns för hur många av dessa funktioner du kan ha så länge de exporteras Atomerna som returneras som NextStateName i tuplarna kommer att avgöra om funktionen kommer att ringas eller inte. I det sista avsnittet nämnde jag globala händelser som skulle utlösa en specifik reaktion oavsett vilken stat vi är i hundens luktande mat kommer att släppa vad det än är Gör och kommer istället leta efter mat För dessa händelser som bör behandlas på samma sätt i varje stat, är handtagets 3 återuppringning det du vill. Funktionen tar argument som liknar StateName 2 med undantag för tha T det accepterar en StateName-variabel mellan dem och berättar vad staten var när händelsen mottogs. Den returnerar samma värden som StateName 2. Handlesyncevent 4 återuppringning är StateName 3 vilket handtag 2 är till StateName 2 Det hanterar synkrona globala händelser , Tar samma parametrar och returnerar samma typ av tupler som StateName 3.Nu kan vara en bra tid att förklara hur vi vet om en händelse är global eller om den är avsedd att skickas till en viss stat. För att bestämma detta kan vi se Vid den funktion som används för att skicka en händelse till FSM Asynkrona händelser riktade mot någon StateName 2-funktion skickas med sendvent 2 synkrona händelser som ska hämtas av StateName 3 ska skickas med syncsendevent 2-3. De två ekvivalenta funktionerna för globala händelser Är sendallstateevent 2 och syncsendallstateevent 2-3 ganska långt namn. Detta fungerar exakt samma som det gjorde för genserver s förutom att det tar en extra tillståndsparameter när den kallas som codechange OldVersion, StateName, Data, E Xtra och returnerar en tuple av formuläret. Detta ska igen fungera lite som vad vi har för generiska servrar avsluta 3 borde göra motsatsen till init 1.Det är dags att lägga allt detta i praktiken Många Erlang tutorials om ändliga - Statliga maskiner använder exempel som innehåller telefonväxlar och liknande saker Det är min gissning att de flesta programmerare sällan måste hantera telefonväxlar för statliga maskiner. På grund av det kommer vi att titta på ett exempel som passar flera utvecklare vi ska designa Och implementera ett handelssystem för något fiktivt och icke-existerande videospel. Designen som jag har valt är lite utmanande Istället för att använda en mäklare genom vilka spelare ruttar föremål och bekräftelser, som uppriktigt sagt skulle bli enklare, kommer vi att genomföra en Server där båda spelarna pratar med varandra direkt, vilket skulle ha fördelen av att vara distribuerbara. Eftersom implementeringen är knepig kommer jag att spendera en bra stund och beskriva den, vilken typ av problem som ska vara f Aced och sätten att fixa dem. Först och främst bör vi definiera de åtgärder som våra spelare kan göra när de handlar. Den första ber om en handel som ska ställas in. Den andra användaren bör också kunna acceptera den handeln vi vann T ge dem rätt att förneka en handel eftersom vi vill hålla sakerna enkla. Det blir enkelt att lägga till den här funktionen när allting är klart. När handeln är klar bör våra användare kunna förhandla med varje Andra Detta innebär att de borde kunna göra erbjudanden och sedan dra tillbaka dem om de vill. När båda spelarna är nöjda med erbjudandet kan de var och en förklara sig redo att slutföra handeln. Därefter ska de sparas någonstans på båda sidor. I tid borde det också vara meningsfullt för någon av spelarna att avbryta hela handeln. Någon åsikt skulle kunna erbjuda endast saker som anses vara ovärderliga för den andra parten, som kan vara mycket upptagen och så ska det vara möjligt att backhanda dem med en välförtjänt Avbokning. I kort sagt följande Åtgärder bör vara möjliga. Ska för en handel. Acceptera en trade. offer-föremål. Stäng ett erbjudande. Självklart som redo. brutalt avbryta handeln. Nu, när var och en av dessa åtgärder vidtas, bör den andra spelarens s FSM bli gjort medveten Av det Detta är meningsfullt, för när Jim berättar att hans FSM skickar ett föremål till Carl, måste Carl s FSM vara medveten om det. Det betyder att båda spelarna kan prata med sin egen FSM som kommer att prata med den andra s FSM Detta ger Oss något som det här. Det första som vi märker när vi har två identiska processer som kommunicerar med varandra är att vi måste undvika synkrona samtal så mycket som möjligt. Anledningen till detta är att om Jim s MSM skickar ett meddelande till Carl s FSM och väntar sedan på sitt svar samtidigt som Carl s FSM skickar ett meddelande till Jims FSM och väntar på sitt eget specifika svar, båda väntar på den andra utan att någonsin svara. Detta fryser effektivt båda FSMs. Vi har ett dödläge En lösning på detta är att vänta på en timeout och sedan gå vidare , Men då kommer det att finnas kvarställningsmeddelanden i båda processerna brevlådor och protokollet kommer att rysas upp. Det är verkligen en burk maskar, och så vill vi undvika det. Det enklaste sättet att göra det är att undvika alla synkrona meddelanden och gå fullt ut Asynkron Observera att Jim fortfarande kan synkronisera till sin egen FSM där det inte finns någon risk här eftersom FSM inte behövde ringa till Jim och så att inget dödläge kan uppstå mellan dem. När två av dessa FSM-enheter kommunicerar kan hela utbytet se ut Lite som detta. Både FSM är i viloläge När du frågar Jim att handla måste Jim acceptera innan sakerna går vidare. Båda kan du erbjuda saker eller dra tillbaka dem. När du både är redo för dig kan handeln ske Det här är en förenklad version av allt som kan hända och vi får se alla möjliga fall med mer detalj i nästa stycke. Här kommer den svåra delen att definiera statsdiagrammet och hur statliga övergångar inträffar. Vanligtvis går en bra del av tanken på detta, för att du Måste tänka på alla de små saker som kan gå fel Några saker kan gå fel även efter att ha granskat det många gånger På grund av detta ska jag helt enkelt sätta den jag bestämde mig för att genomföra här och sedan förklara det. Först, båda ändliga Statliga maskiner börjar i viloläge Vid den här tiden kan vi fråga en annan spelare att förhandla med oss. Vi går in i viloläge för att vänta på ett eventuellt svar efter att vår FSM har skickat efterfrågan. När den andra FSM skickar Svaret vårt kan byta till förhandla. Den andra spelaren bör också vara i förhandlingar efter det här. Om vi ​​kan bjuda in den andra kan den andra bjuda in oss. Om allt går bra, så borde det äntligen se ut så här. Så här är det här Tämligen motsatsen som de två tidigare statliga diagrammen sammanfogade i en Obs! Vi förväntar oss att spelaren accepterar erbjudandet i det här fallet. Vad händer om det med stor lycka vi ber den andra spelaren att handla med oss ​​samtidigt som han ber oss att Handel. Vad händer här är att båda kunderna Fråga sin egen FSM att förhandla med den andra. Så snart frågeställningarna skickas skickar båda FSM: erna till viloläge. Då kan de behandla förhandlingsfrågan. Om vi ​​granskar tidigare statsdiagram ser vi att denna kombination av Händelser är den enda gången vi kommer att få fråga förhandla meddelanden medan det är i viloläge. Därför vet vi att få dessa meddelanden i viloläge innebär att vi slår tävlingsvillkoren och kan anta att båda användare vill prata med varandra. Vi kan flytta dem båda. Att förhandla om staten Hooray. So nu vi återförhandlingar Enligt listan över åtgärder som jag listade tidigare måste vi stödja användare som erbjuder varor och sedan dra in erbjudandet. Alla det här gör vi vidarebefordra vårt kunds meddelande till de andra FSM Both finite-state maskinerna Kommer att behöva hålla en lista över objekt som erbjuds av endera spelaren, så de kan uppdatera den listan när de får sådana meddelanden. Vi stannar i förhandlingsstaten efter det kanske den andra spelaren vill erbjuda saker också. Här fungerar vår FSM i princip på ett liknande sätt Det här är normalt När vi är trött på att erbjuda saker och tycker att vi är generösa nog, måste vi säga att vi är redo att offisera handeln Eftersom vi måste synkronisera båda spelarna måste vi Använd ett mellanstatligt tillstånd, som vi gjorde för viloläge och vilseledande. Vad vi gör här är att så snart vår spelare är redo frågar vår FSM Jims FSM om han är redo. I väntan på sitt svar faller vår egen FSM i sin väntetillstånd. Svaret vi får kommer bero på Jim s FSM-stat om det är i vänteläge, det kommer att berätta för oss att det är klart Annars kommer det att berätta för oss att det inte är klart ännu Det är exakt vad vår FSM automatiskt svarar på Jim om han Frågar oss om vi är redo när vi förhandlar om tillstånd. Vår finita statsapparat kommer att förbli i förhandsläge tills vår spelare säger att han är redo. Kom igen och antar att han gjorde det och vi är nu i väntan. Men Jim är inte där än. Det betyder att När vi förklarade oss som redo, har vi frågat Jim om han också var redo och hans FSM kommer Har inte svarat ännu. Han är inte redo, men vi är Vi kan inte göra mycket men fortsätt att vänta Medan vi väntar efter Jim, som fortfarande förhandlar fram förresten, är det möjligt att han kommer att försöka skicka oss fler föremål eller kanske avbryta hans Tidigare erbjudanden. Naturligtvis vill vi undvika att Jim tar bort alla sina saker och sedan klickar på Jag är redo och skruvlar oss över i processen Så fort han ändrar de erbjudna objekten går vi tillbaka till förhandlingsstaten så att vi antingen kan ändra Vårt eget erbjudande eller undersöka den nuvarande och bestämma att vi är redo Skölj och repetera. Vid en viss tidpunkt kommer Jim att vara redo att slutföra handeln. När det händer kommer hans ändliga maskin att fråga oss om vi är redo. FSM gör det svaret att vi verkligen är redo Vi håller oss i vänteläge och vägrar att flytta till redo tillståndet, men varför är det Eftersom det är ett potentiellt rasförhållande Föreställ dig att följande sekvens av händelser äger rum utan att göra det nödvändiga steget. Är lite komplex, så jag kommer att förklara på grund av wa Y-meddelanden mottas, vi kan eventuellt bara behandla objektet efter att vi förklarade oss redo och även efter att Jim förklarade sig redo. Det innebär att så snart vi läser erbjudandemeddelandet byter vi tillbaka till förhandlingsstaten. Under den tiden kommer Jim att Har berättat att han är redo Om han skulle byta stater där och fortsätta att vara redo som illustrerad ovan, blir han fångad i obestämd tid medan vi inte skulle veta vad i helvete att göra. Det kan också hända tvärtom Ugh. One Sätt att lösa detta är att lägga till ett lager av indirection tack vare david wheeler Det är därför vi stannar i vänteläge och skickar redo som visas i vårt tidigare statsdiagram Här är hur vi hanterar det färdiga meddelandet, förutsatt att vi redan var redo Berätta för att vi berättade för vår MSM var vi redo redan. När vi blir redo från andra MSM skickar vi oss redo igen Det här är för att se till att vi inte har tävlingsvillkor som nämns ovan Detta kommer att skapa en överflödig klar messa Ge i en av de två FSMs, men vi måste bara ignorera det i det här fallet Vi skickar sedan ett ack meddelande och Jim s FSM kommer att göra detsamma innan vi flyttar till redo tillståndet Anledningen till att detta ack-meddelande finns finns på grund av att vissa Implementeringsdetaljer om synkroniseringsklienter Jag har lagt det i diagrammet för att det ska bli rätt, men jag vann inte att förklara det förrän Glöm det för tillfället Vi lyckades äntligen synkronisera båda spelarna Whew. So nu är det redo tillståndet. Är lite speciell Båda spelarna är redo och har i grunden givit finit-state-maskinerna all den kontroll de behöver. Det gör att vi kan implementera en bastardiserad version av en tvåfas-commit för att se till att saker går rätt när vi gör trade official. Our version som Beskrivet ovan kommer att vara ganska förenklat. Att skriva ett riktigt korrekt tvåfas-commit skulle kräva mycket mer kod än vad som är nödvändigt för oss att förstå finitesta maskiner. För det första måste vi bara tillåta att handeln avbryts när som helst. Det betyder att tha T på något sätt oavsett vilken stat vi befinner oss i, vi kommer att lyssna på avbokningsmeddelandet från båda sidor och avsluta transaktionen. Det bör också vara gemensamt med tillstånd att låta den andra sidan veta att vi är borta innan vi lämnar. Det är så mycket Av information att absorbera på en gång, oroa dig inte om det tar ett tag att helt förstå det Det tog massor av människor att titta över mitt protokoll för att se om det var rätt, och även då missade vi alla några loppförhållanden som jag då fångade Några dagar senare när du granskar koden medan du skriver den här texten Det är normalt att du behöver läsa det mer än en gång, särskilt om du inte är van vid asynkrona protokoll. Om så är fallet uppmuntrar jag dig till att försöka skapa ett eget protokoll Fråga dig själv vad som händer om två personer gör samma åtgärder mycket snabbt. Om de kedjar två andra händelser snabbt. Vad gör jag med meddelanden som jag inte hanterar när du byter stater. Du kommer se att komplexiteten blir riktigt snabb. Du kan hitta en liknande lösning Att gruva, eventuellt en satsning För en, låt mig veta om så är fallet Oavsett resultatet, det är väldigt intressant att arbeta med och våra FSMs är fortfarande relativt enkla. När du har smält allt detta eller tidigare, om du är rebellläsare, kan du Gå till nästa avsnitt där vi implementerar spelsystemet För närvarande kan du ta en trevlig kaffepaus om du känner för att göra det. Det första som måste göras för att implementera vårt protokoll med OTP s genfsm är att skapa gränssnittet där Kommer att vara 3 ringer för vår modul spelaren, genfsm-beteendet och den andra spelaren s FSM Vi behöver bara exportera spelarfunktionen och genfsm-funktionerna, även om det här beror på att den andra FSM-enheten också kommer att köras inom fackmodulen och kan komma åt dem Från insidan. Så det är vårt API Du kan se att jag planerar att ha några funktioner som är synkrona och asynkrona Det här beror främst på att vi vill att vår kund ska ringa oss synkront i vissa fall, men den andra FSM kan göra det asynkront. Klientsynkronisering Ronous förenklar vår logik en hel del genom att begränsa antalet motsägelsefulla meddelanden som kan skickas efter varandra. Vi kommer dit. Låt oss först implementera själva offentliga API enligt protokollet som definierats ovan. Detta är ganska standard alla dessa genfsm-funktioner har Tagits förut förutom start 3-4 och startlink 3-4 som jag tror att du kan räkna ut i det här kapitlet. Nästa ska vi implementera FSM till FSM-funktioner De första har att göra med handelsuppsättningar när vi först vill fråga Annan användare att gå med i en handel. Den första funktionen frågar den andra pid om de vill handla och den andra används för att svara på det asynkront. Naturligtvis kan vi skriva funktionerna att erbjuda och avbryta erbjudanden. Vårt protokoll ovan är det här de borde vara. Så nu vi har fått dessa samtal måste vi fokusera på vila De återstående samtalen gäller att vara redo eller inte och hantera det slutliga engagemanget igen, med tanke på vårt protokoll ovan Vi har tre samtal ar Eyouready som kan få svaren notyet eller ready. The enda funktioner som finns kvar är de som ska användas av båda FSMs när de begår i redo tillståndet. Den exakta användningen kommer att beskrivas mer i detalj senare, men för närvarande är namnen och Sekvensstatsdiagrammet från tidigare bör vara tillräckligt Men du kan fortfarande transkribera dem till din egen version av tradefsm. Och det är också funktionen med artighet som gör det möjligt för oss att varna den andra FSM som vi avbröt handeln. Vi kan nu flytta till det riktiga Intressant del genfsm callbacks Den första återuppringningen är init 1 I vårt fall vill vi att varje FSM ska hålla namnet på användaren det representerar det sättet, vår produktion blir trevligare i de data som den fortsätter att vidarebefordra till sig själv Vad gör vi mer Vill hålla i minnet I vårt fall vill vi ha den andra s pid, de objekt vi erbjuder och de andra artiklarna Vi kommer också att lägga till referens för en bildskärm så vi vet att avbryta om den andra dör och ett från fält , Brukade göra fördröjda svar. I casen E av init 1 vi kommer bara bryr oss om vårt namn för nu Observera att vi kommer att börja i viloläge. Några återkopplingar att överväga skulle vara staterna själva Hittills har jag beskrivit de statliga övergångarna och samtalen som kan göras, men vi Jag behöver ett sätt att se till att allt går bra Vi ska skriva några verktygsfunktioner först. Och vi kan börja med viloläge För konventionens skull kommer jag att täcka den asynkrona versionen först. Den här borde inte behöva bry sig om någonting annat än Den andra spelaren som frågar efter en handel som ges vår egen spelare, om du tittar på API-funktionerna, kommer att använda ett synkront samtal. En bildskärm är inställd för att vi ska kunna hantera den andra döende och dess ref lagras i FSM s data Tillsammans med den andra s pid innan du flyttar till viloläge. Observera att vi kommer att rapportera alla oväntade händelser och ignorera dem genom att stanna i det tillstånd vi redan var i. Vi kan få några utgående bandmeddelanden här och där som kan vara resultatet Av tävlingsförhållanden Det är vanligtvis säkert att ignorera dem , Men vi kan inte lätt bli av med dem. Det är bara bättre att inte krascha hela FSM på dessa okända men något förväntade meddelanden. När vår egen kund ber MSM att kontakta en annan spelare för en handel kommer det att skicka en synkron händelse Den inaktiv 3 återkallningen kommer att behövas. Vi fortsätter på ett sätt som liknar den asynkrona versionen, förutom att vi faktiskt behöver fråga den andra sidan om de vill förhandla med oss ​​eller inte. Du kommer märka att vi inte svarar på klienten ännu Beror på att vi inte har något intressant att säga och vi vill att kunden är låst och väntar på att handeln ska accepteras innan något görs. Svaret kommer bara att skickas om den andra sidan accepterar när vi återvänder. När vi återvänder, har vi Att ta itu med den andra som accepterar att förhandla och den andra ber om att förhandla om resultatet av ett tävlingsförhållande, vilket beskrivs i protokollet. Detta ger oss två övergångar till förhandlingsstaten, men kom ihåg att vi måste använda genfsm svar 2 svara på vår kund Att berätta det är okej Y för att börja erbjuda varor Det är också fallet med vår MUSS-klient som accepterar handeln som föreslagits av den andra parten. I och med att den här flyttas till förhandlingsstaten Här måste vi hantera asynkrona frågor för att lägga till och ta bort objekt som kommer både från Klient och den andra FSM Men vi har ännu inte bestämt hur man lagrar varor För att jag är lite lat och antar att användarna vann inte handla så många saker, kommer enkla listor att göra det för nu Men vi kanske ändrar oss på en senare punkt , Så det är en bra idé att paketera objektoperationer i sina egna funktioner Lägg till följande funktioner längst ner i filen med meddelande 3 och oväntat 2.Simple men de har roll att isolera åtgärderna som lägger till och tar bort objekt från deras Implementering med hjälp av listor Vi kan enkelt flytta till proplister, arrayer eller vilken datastruktur som helst utan att störa resten av koden. Användning av båda dessa funktioner kan vi genomföra erbjuda och ta bort objekt. Detta är en ful aspekt av att använda asynkrona röra Åldrar på båda sidor En uppsättning meddelanden har formuläret att göra och dra tillbaka, medan den andra har gjort och ångra. Det här är helt godtyckligt och används endast för att skilja mellan kommunikation mellan FSM-FSM och FSM-kommunikation. Notera att på de kommande Från vår egen spelare måste vi berätta för den andra sidan om de förändringar vi gör. Ett annat ansvar är att hantera det tidigare meddelandet vi nämnde i protokollet. Detta är den sista asynkronhändelsen som ska hanteras i förhandlingsstaten. Som beskrivs i Protokollet, när vi inte är i väntan och mottar detta meddelande måste vi svara med notyet. Var också utfärda handelsuppgifter till användaren så att ett beslut kan fattas. När ett sådant beslut fattas och användaren är redo, är den färdiga händelsen Kommer att skickas Den här ska vara synkron eftersom vi inte vill att användaren ska fortsätta ändra sitt erbjudande genom att lägga till objekt medan han hävdar att han är redo. Vid denna punkt måste en övergång till väntetillståndet göras Observera att bara väntar på den andra Är inte intressant Vi sparar Från-variabeln så att vi kan använda den med genfsm svar 2 när vi har något att berätta för kunden. Väntetillståndet är ett roligt odjur Nya objekt kan erbjudas och dras in, eftersom den andra användaren kanske inte är redo. Det är därför meningsfullt att automatiskt återgå till förhandlingsstaten. Det skulle suga att ha bra saker som erbjuds oss, bara för den andra att ta bort dem och förklara sig redo, stjäla vår loot. Att gå tillbaka till förhandlingar är ett bra beslut. Nu är det s Något meningsfullt och vi svarar på spelaren med de koordinater vi lagrade i. Den nästa uppsättningen meddelanden som vi behöver oroa sig över är de som hör samman med att synkronisera båda FSM så att de kan flytta till färdigt tillstånd och bekräfta handeln För den här borde vi verkligen Fokusera på det tidigare definierade protokollet. De tre meddelanden vi kan få är redan berodde på att den andra användaren bara förklarat sig redo, inte för att vi frågade den andra om han var redo och att han inte var redo eftersom vi frågade t Han andra om han var redo och han var. Vi ska börja med isyouready Kom ihåg att i protokollet sa vi att det kunde finnas ett tävlingsvillkor dolt där Det enda vi kan göra är att skicka det färdiga meddelandet med redan 1 och ta itu med resten Senare. Vi sitter fast och väntar igen, så det är inte värt att svara på vår klient. Likväl vann vi inte svara på klienten när den andra sidan skickar ett meddelande till vår inbjudan. Å andra sidan, om den andra är klar, Vi skickar ett extra klart meddelande till den andra FSM, svara på vår egen användare och sedan flytta till färdigt tillstånd. Du kanske har märkt att jag har använt acktrans 1 Faktum är att båda FSMs ska använda det. Varför är detta För att förstå detta har vi För att börja titta på vad som händer i redo tillståndet. När i redo tillståndet blir båda spelarnas handlingar värdelösa, utom att avbryta Vi vann inte hand om nya artiklarbjudanden Det ger oss lite frihet I princip kan båda FSM: erna fritt tala utan att oroa sig Om resten av världen Detta låter oss implementera vårt Bastardisering av en tvåfas commit För att börja detta begå utan att någon spelare agerar behöver vi en händelse för att utlösa en handling från FSMs. Ack-händelsen från acktrans 1 används för det så snart meddelandet är klart Behandlas och ageras när transaktionen kan börja. Tvåfasförpliktelser kräver synkron kommunikation, men det betyder att vi inte kan få båda FSM: erna att starta transaktionen på en gång, för att de kommer att hamna i dödläge. Hemligheten är att hitta ett sätt att bestämma den där Ändlig statlig maskin bör starta förbindelsen medan den andra kommer att sitta och vänta på order från den första. Det visar sig att ingenjörerna och datavetenskaparna som designade Erlang var ganska smarta bra visste vi att redan Pids av någon process kan vara Jämfört med varandra och sorterade Detta kan göras oavsett när processen har skottats, oavsett om den fortfarande lever eller inte, eller om den kommer från en annan VM så kommer vi se mer om detta när vi kommer in i distribuerade Erlang. Bekräftar att två Pids kan jämföras och en kommer att vara större än den andra, vi kan skriva en funktionsprioritet 2 som tar två pekar och berättar om det är vald eller inte. Och genom att ringa den funktionen kan vi ha en process som börjar Begå och den andra följer ordern. Här är vad det här ger oss när det ingår i redo tillståndet efter att ha mottagit ack meddelandet. Detta stora försök fångar uttryck är den ledande FSM-beslutet hur engagemanget fungerar. Både askcommit 1 och docommit 1 är synkrona Detta Låter den ledande FSM kalla dem fritt Du kan se att den andra FSM bara går och väntar Det kommer då att få order från den ledande processen Det första meddelandet ska vara askcommit Detta är bara för att se till att båda FSMs fortfarande finns där inget fel hände, de Är båda dedikerade till att fullfölja uppgiften. När detta är mottaget kommer den ledande processen att be om att bekräfta transaktionen med docommit Det är när vi måste begå våra data. Och när det är gjort lämnar vi Den ledande FSM kommer att få ok Som ett svar och kommer att veta att begå i sin egen slut efteråt Det förklarar varför vi behöver det stora försöket om den svarande FSM dör eller dennes spelare avbryter transaktionen, de synkrona samtalen kommer att krascha efter en timeout. Fördraget bör avbrytas i det här fallet . Bara så du vet, jag definierade commit-funktionen som följer. Pappa underwhelming, eh Det är i allmänhet inte möjligt att göra ett riktigt säkert engagemang med bara två deltagare en tredje part är vanligtvis krävs för att bedöma om båda spelarna gjorde allt rätt Om du var Att skriva en sann commit-funktion borde den kontakta den tredje parten på båda spelarnas vägnar och sedan skriva det till en databas för dem eller återlämna hela utbytet. Vi vann inte att gå in i sådana detaljer och den aktuella commit 1-funktionen kommer att vara Tillräckligt för behoven av den här boken. Vi är inte färdiga ännu Vi har ännu inte täckt två typer av händelser som en spelare avbryter handeln och den andra spelarens s finite state machine crashing. Den förra kan hanteras med hjälp av callbacks han Dleevent 3 och handlesyncevent 4 När den andra användaren avbryter får vi en asynkron anmälan. När vi gör det får vi inte glömma att berätta för den andra innan vi slutar oss. Och voil Den sista händelsen att ta hand om är när den andra FSM går ner Lyckligtvis hade vi satt en bildskärm tillbaka i viloläge. Vi kan matcha det här och reagera i enlighet. Notera att även om annullerings - eller NED-händelserna händer när vi återkommer i förbindelsen, bör allt vara säkert och ingen ska få sina föremål stulna. Observera att vi använde io-format 2 för de flesta av våra meddelanden för att låta FSM: erna kommunicera med sina egna kunder. I en verklig världsapplikation kanske vi vill ha något mer flexibelt än det enda sättet att göra är att låta klienten skicka in en Pid, ​​vilket 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