Thursday, 19 October 2017

Erlang trading system no Brasil


25 Maio 16 00 BST 15 00 UTC 17 00 CET 08 00 PDT A Sportrisq é uma corretora e distribuidora de soluções e produtos de gestão de risco para a indústria desportiva. Ouça a CTO Justin Worall descreve o processo de migração de dois componentes da plataforma central de Python para Erlang o subjacente Os problemas envolvidos, os benefícios percebidos de Erlang nessas situações, o processo de tomada de decisão, a aplicação desenhos e os resultados. Em este Webinar, você ll learn. The processo de migração de baixa latência Python componentes para Erlang. The processo de tomada de decisão. Aplicação Desenhos e resultados. Learn você alguns Erlang. Hey lá, parece que seu Javascript está desativado Isso é bom, o site funciona sem ele No entanto, você pode preferir lê-lo com realce de sintaxe, que requer Javascript. Rage Contra as máquinas Finite-State. Uma máquina de estados finitos FSM não é realmente uma máquina, mas tem um número finito de estados. Eu sempre encontrei máquinas de estado finito mais fáceis de entender com gráficos e diagramas. Por exemplo, o seguinte seria um diagrama simplista para um cão muito mudo como uma máquina de estado. Aqui o cão tem 3 estados sentados, latidos ou abanando a cauda. Diferentes eventos ou entradas podem forçá-lo a mudar seu estado. Se um cão está sentado calmamente e No entanto, se o cão está sentado e você pet it, não temos idéia do que poderia acontecer No mundo Erlang, o cão poderia falhar e, eventualmente, ser reiniciado por Seu supervisor No mundo real que seria um evento freaky, mas seu cão iria voltar depois de ser atropelado por um carro, por isso não é tudo ruim. Aqui está um diagrama de estado de gato s para uma comparação. Este gato tem um único estado , E nenhum evento pode nunca mudá-lo. Implementar a máquina de estado do gato em Erlang é uma tarefa divertida e simples. Podemos tentar o módulo para ver que o gato realmente nunca dá uma porcaria. O mesmo pode ser feito para o FSM cão, exceto mais Estados devem estar disponíveis. Deve ser relativamente simples combinar cada um dos estados e Ansiedades para o que estava no diagrama acima Aqui é o FSM em use. You pode acompanhar o esquema, se você quiser eu costumo fazer, isso ajuda a ter certeza de que nada está errado. Isso é realmente o núcleo de FSMs implementado como Erlang processos lá São coisas que poderiam ter sido feitas de forma diferente que poderia ter passado estado nos argumentos das funções de estado de uma forma semelhante ao que fazemos com os servidores principal loop Poderíamos também ter adicionado um init e terminar funções, manipulou atualizações de código, etc. Another Diferença entre o cão e gato FSMs é que os eventos do gato s são síncronas e os eventos do cão s são assíncronos Em um FSM real, ambos poderiam ser usados ​​de forma mista, mas eu fui para a representação mais simples de pura preguiça inexplorada Há Outras formas de evento os exemplos não mostram eventos globais que podem acontecer em qualquer estado. Um exemplo de tal evento pode ser quando o cão fica cheirando o alimento Uma vez que o evento cheiro alimento é acionado, não importa o estado que o cão está em Ele iria Procurando a fonte de alimento. Agora nós não gastaremos muito tempo implementando tudo isso em nosso FSM escrito em um guardanapo. Em vez disso, vamos mover diretamente para o comportamento de genfsm. O comportamento de genfsm é algo semelhante ao genserver em que ele É uma versão especializada da mesma A maior diferença é que, ao invés de lidar com chamadas e moldes, estamos lidando com eventos síncronos e assíncronos. Muito parecido com nossos exemplos de cães e gatos, cada estado é representado por uma função Novamente, vamos passar pelos callbacks que nossos módulos precisam Para implementar a fim de trabalhar. Esta é a mesma init 1 usado para servidores genéricos, exceto os valores de retorno aceitos são e The stop tuple funciona da mesma maneira que para genserver s, e hibernate e Timeout manter a mesma semântica. Novo aqui é que StateName variável StateName é um átomo e representa a próxima função callback para ser chamado. As funções StateName 2 e StateName 3 são nomes de placeholder e você deve decidir o que eles serão Vamos supor o init 1 Função retorna a tupla Isso significa que a máquina de estado finito será em um estado sentado Este não é o mesmo tipo de estado que vimos com genserver é bastante equivalente aos estados sentar bark e wagtail do anterior FSM cão Estes estados ditam um Contexto em que você lidar com um determinado evento. Um exemplo disso seria alguém chamá-lo em seu telefone Se você estiver no estado dormindo em um sábado de manhã, sua reação pode ser para gritar no telefone Se o seu estado está à espera de um emprego Entrevista, as chances são que você vai pegar o telefone e responder educadamente Por outro lado, se você está no estado morto, então eu estou surpreso que você pode até mesmo ler este texto em all. Back para o nosso FSM A função init 1 disse que devemos No estado sentado Sempre que o processo genfsm recebe um evento, quer a função sentada 2 ou sentada 3 será chamada A função sentada 2 é chamada para eventos assíncronos e sentada 3 para síncronos. Os argumentos para sentar 2 ou, em geral, Event a mensagem real enviada como um evento e StateData os dados que foram transportados sobre as chamadas sentando 2 podem então retornar as tuplas e. Os argumentos para sentar 3 são semelhantes, exceto que há uma variável From entre Event e StateData A variável From É usado exatamente da mesma maneira como era para o genserver s, incluindo o genfsm resposta 2 O StateName 3 funções podem retornar o seguinte tuples. Note que não há limite em quantas dessas funções você pode ter, enquanto eles são exportados Os átomos retornados como NextStateName nos tuplas irão determinar se a função será chamado ou não. Na última seção, eu mencionei eventos globais que desencadeariam uma reação específica, não importa qual estado nós estamos no cão com cheiro de comida vai cair o que quer que seja Fazendo e em vez procurar comida Para esses eventos que devem ser tratados da mesma forma em cada estado, o handleevent 3 callback é o que você quer A função leva argumentos semelhantes ao StateName 2 com a exceção tha T ele aceita uma variável StateName entre eles, dizendo-lhe o que o estado era quando o evento foi recebido Ele retorna os mesmos valores como StateName 2.The handlesyncevent 4 callback é para StateName 3 o que handleevent 2 é para StateName 2 Ele lida com eventos globais síncronos , Leva os mesmos parâmetros e retorna o mesmo tipo de tuplas como StateName 3.Now pode ser um bom momento para explicar como sabemos se um evento é global ou se ele s destinado a ser enviado para um estado específico Para determinar isso, podemos olhar Na função usada para enviar um evento para o FSM Eventos assíncronos destinados a qualquer função StateName 2 são enviados com sendevent 2 eventos síncronos a serem capturados por StateName 3 devem ser enviados com syncsendevent 2-3. As duas funções equivalentes para eventos globais São sendallstateevent 2 e syncsendallstateevent 2-3 bastante um nome longo. Isto funciona exatamente o mesmo que fez para genserver s, exceto que ele tem um parâmetro de estado extra quando chamado como codechange OldVersion, StateName, Data, E Xtra e retorna uma tupla do form. This deve, novamente, agir um pouco como o que temos para servidores genéricos terminate 3 deve fazer o oposto do init 1.It s tempo para colocar tudo isso na prática Muitos tutoriais Erlang sobre finite - As máquinas de estado usam exemplos que contêm interruptores de telefone e coisas similares É o meu palpite que a maioria dos programadores raramente terá que lidar com interruptores de telefone para máquinas de estado Por isso, vamos olhar um exemplo que é mais apropriado para muitos desenvolvedores que vamos projetar E implementar um sistema de negociação de itens para algum jogo de vídeo fictício e não existente. O projeto que eu escolhi é um pouco desafiador Ao invés de usar um corretor através do qual os jogadores rota itens e confirmações que, francamente, seria mais fácil, vamos implementar um Servidor onde ambos os jogadores falam uns aos outros diretamente que teria a vantagem de ser distributable. Porque a implementação é complicada, vou passar um bom tempo descrevendo, o tipo de problemas a ser f Aced e as formas de corrigi-los. Primeiro de tudo, devemos definir as ações que podem ser feitas por nossos jogadores quando a negociação O primeiro é pedir um comércio a ser criado O outro usuário também deve ser capaz de aceitar que o comércio Nós ganhamos T dar-lhes o direito de negar um comércio, no entanto, porque queremos manter as coisas simples Será fácil adicionar este recurso uma vez que a coisa toda é feita. Uma vez que o comércio é criado, os nossos usuários devem ser capazes de negociar com cada um Outros Isso significa que eles devem ser capazes de fazer ofertas e, em seguida, retractá-los se quiserem Quando ambos os jogadores estão satisfeitos com a oferta, cada um pode declarar-se como pronto para finalizar o comércio Os dados devem ser salvos em algum lugar em ambos os lados Em qualquer ponto No tempo, também deve fazer sentido para qualquer um dos jogadores para cancelar todo o comércio Alguns pleb poderia estar oferecendo apenas itens considerados indignos para a outra parte que pode ser muito ocupado e por isso deve ser possível backhand-los com um merecido Em suma, os seguintes As ações devem ser possíveis. Para um trade. accept um trade. offer items. retract uma oferta. declare self como ready. brutally cancelar o trade. Now, quando cada uma dessas ações é tomada, o FSM do outro jogador deve ser informado Isso faz sentido, porque quando Jim diz a sua FSM para enviar um item para Carl, FSM Carl tem que ser conscientizados Isso significa que ambos os jogadores podem conversar com sua própria FSM, que vai falar com os outros FSM Isso dá Nós algo um pouco como this. A primeira coisa a notar quando temos dois processos idênticos comunicar uns com os outros é que temos que evitar chamadas síncronas, tanto quanto possível A razão para isso é que se Jim s FSM envia uma mensagem para Carl s FSM e, em seguida, aguarda a sua resposta, enquanto ao mesmo tempo Carl s FSM envia uma mensagem para Jim s FSM e aguarda a sua própria resposta específica, ambos acabam esperando o outro sem nunca responder Isso efetivamente bloqueia FSMs Nós temos um impasse . Uma solução para isso é esperar por um tempo limite e, em seguida, avançar , Mas então haverá mensagens de sobra em caixas de correio de ambos os processos eo protocolo será confuso Isso certamente é uma lata de worms, e por isso queremos evitá-lo. A maneira mais simples de fazê-lo é evitar todas as mensagens síncronas e ir totalmente Assíncrono Note que Jim pode ainda fazer uma chamada síncrona para o seu próprio FSM não há nenhum risco aqui, porque o FSM ganhou t necessidade de chamar Jim e assim nenhum impasse pode ocorrer entre eles. Quando dois destes FSMs se comunicam juntos, toda a troca pode olhar Um pouco como this. Both FSMs estão em um estado ocioso Quando você pede Jim para o comércio, Jim tem que aceitar antes que as coisas se movem Em seguida, tanto de você pode oferecer itens ou retirá-los Quando ambos estão declarando-se pronto, o comércio pode ter lugar Esta é uma versão simplificada de tudo o que pode acontecer e vamos ver todos os casos possíveis com mais detalhes nos próximos paragraphs. Here vem a parte difícil definir o diagrama de estado e como as transições de estado acontecem Normalmente um bom pouco de pensamento vai para isso, porque você Tem que pensar em todas as pequenas coisas que poderiam dar errado Algumas coisas podem dar errado, mesmo depois de ter revisto muitas vezes Por isso, vou simplesmente colocar o que eu decidi aplicar aqui e, em seguida, explicar it. At primeiro, As máquinas de estado começam no estado ocioso Neste ponto, uma coisa que podemos fazer é pedir a algum outro jogador para negociar com us. We ir para o modo idlewait, a fim de esperar uma eventual resposta após o FSM enviou a demanda Uma vez que o outro FSM envia A resposta, o nosso pode mudar para negociar. O outro jogador também deve estar em estado de negociação após isso Obviamente, se podemos convidar o outro, o outro pode convidar-nos Se tudo correr bem, isso deve acabar olhando como este. Então isso é Muito bem o oposto como os dois diagramas de estado anteriores empacotados em uma Nota que esperamos que o jogador a aceitar a oferta neste caso O que acontece se, por pura sorte, pedimos o outro jogador para o comércio com a gente, ao mesmo tempo, ele nos pede para O que acontece aqui é que ambos os clientes Pedir a sua própria FSM para negociar com a outra Assim que as mensagens de pedir negociar são enviados, ambos os FSMs mudar para o estado idlewait Então, eles serão capazes de processar a questão de negociação Se analisarmos os diagramas de estado anterior, vemos que esta combinação de Eventos é a única vez que vamos receber mensagens de negociação perguntar no estado idlewait Por conseguinte, sabemos que recebendo essas mensagens em idlewait significa que atingimos a condição de corrida e pode assumir ambos os usuários querem conversar uns com os outros Podemos mover ambos Para negociar estado Hooray. So agora estamos negociando De acordo com a lista de ações que eu listei anteriormente, devemos apoiar os usuários oferecendo itens e, em seguida, retrair a oferta. Todo isso faz é encaminhar a mensagem do nosso cliente para o outro FSM Ambos máquinas de estado finito Será necessário manter uma lista de itens oferecidos por qualquer jogador, para que eles possam atualizar essa lista ao receber essas mensagens Nós ficamos no estado de negociação após este talvez o outro jogador quer oferecer itens também. Aqui, o nosso FSM basicamente age de uma maneira semelhante. Isso é normal. Uma vez que nos cansamos de oferecer coisas e achamos que somos generosos o suficiente, temos que dizer que estamos prontos para oficializar o comércio. Porque temos que sincronizar ambos os jogadores, teremos que Usar um estado intermediário, como fizemos para ocioso e idlewait. What nós fazemos aqui é que assim que nosso jogador está pronto, nosso FSM pergunta Jim s FSM se ele está pronto Pending sua resposta, nosso próprio FSM cai em seu estado de espera O A resposta que nós obteremos dependerá do estado de Jim s FSM se está no estado da espera, ele ll diz-nos que está pronto Se não, ele ll diz-nos que não está pronto ainda Que é precisamente o que nosso FSM responde automaticamente a Jim se ele Nos pergunta se estamos prontos quando em estado de negociação. Nossa máquina de estado finito permanecerá em modo de negociação até que nosso jogador diz que ele está pronto Vamos supor que ele fez e estamos agora no estado de espera No entanto, Jim não está lá ainda Isso significa que Quando nos declaramos prontos, teremos perguntado a Jim se ele também estava pronto e seu FSM Não respondeu ainda. Ele não está pronto, mas nós somos Nós não podemos fazer muito, mas continuar esperando Enquanto espera após Jim, que ainda está negociando a propósito, é possível que ele vai tentar nos enviar mais itens ou talvez cancelar seu As ofertas anteriores. Claro, queremos evitar Jim removendo todos os seus itens e, em seguida, clicando Eu estou pronto, enroscando-nos sobre o processo Assim que ele muda os itens oferecidos, vamos voltar para o estado de negociação para que possamos modificar Nossa própria oferta, ou examinar a atual e decidir que estamos prontos Enxaguar e repetir. Em algum ponto, Jim estará pronto para finalizar o comércio também Quando isso acontece, sua máquina de estado finito vai perguntar a nossa se estamos prontos. FSM faz é responder que estamos realmente prontos Nós ficamos no estado de espera e se recusam a passar para o estado pronto embora Por que isso é porque existe uma condição de corrida potencial Imagine que a seguinte seqüência de eventos ocorre, sem fazer este passo necessário. É um pouco complexo, então eu vou explicar Por causa do wa As mensagens de y são recebidas, nós poderíamos possivelmente somente processar a oferta do artigo depois que nós nos declaramos prontos e também depois que Jim declarou-se como pronto Isto significa que assim que nós lemos a mensagem da oferta, nós mudamos de volta ao estado de negociação Durante esse tempo, Nos disse que ele está pronto Se ele fosse mudar os estados lá e passar para pronto como ilustrado acima, ele seria pego esperando indefinidamente, enquanto nós wouldn t sabe o que diabos a fazer Isso também poderia acontecer ao contrário Ugh. One Maneira de resolver isso é adicionando uma camada de indireção Graças a David Wheeler É por isso que ficamos no modo de espera e enviar pronto como mostrado em nosso diagrama de estado anterior Aqui é como lidar com essa mensagem pronta, supondo que já estávamos no pronto Estado, porque dissemos ao nosso FSM que estávamos prontos de antemão. Quando recebemos pronto a partir do outro FSM, enviamos pronto de volta Este é para se certificar de que não teremos a condição de dupla raça mencionado acima Isto irá criar um messa pronto supérfluo Em um dos dois FSMs, mas vamos apenas ter que ignorá-lo neste caso, em seguida, enviar uma mensagem ack e do FSM Jim fará o mesmo antes de passar para estado pronto A razão pela qual esta mensagem ack existe é devido a alguns Detalhes de implementação sobre a sincronização de clientes Eu colocá-lo no diagrama para o bem de ser correto, mas eu não vou explicar até mais tarde Esqueça sobre isso por agora Nós finalmente conseguiu sincronizar os dois jogadores Whew. So agora há o estado pronto Este É um pouco especial Ambos os jogadores estão prontos e, basicamente, dado as máquinas de estado finito todo o controle que eles precisam Isso nos permite implementar uma versão bastardized de um commit de duas fases para se certificar de que as coisas vão para a direita ao fazer o trade oficial. Descrito acima será bastante simplista Escrevendo uma confirmação de duas fases verdadeiramente correta exigiria muito mais código do que o necessário para que possamos entender máquinas de estado finito. Finalmente, só temos que permitir que o comércio seja cancelado a qualquer momento. Isso significa Tha T de alguma forma, não importa em que estado estamos re, vamos indo para ouvir a mensagem de cancelamento de ambos os lados e sair da transação Também deve ser cortesia comum para deixar o outro lado sabe que estamos antes de ir away. Alright É um lote inteiro De informações para absorver de uma vez Não se preocupe se demorar um pouco para compreendê-lo completamente Levou um monte de gente para olhar sobre o meu protocolo para ver se era certo, e mesmo assim todos nós perdemos algumas condições de corrida que eu peguei Alguns dias mais tarde, quando rever o código ao escrever este texto É normal ter necessidade de lê-lo mais de uma vez, especialmente se você não está acostumado a protocolos assíncronos Se este for o caso, eu incentivá-lo inteiramente a tentar criar seu próprio protocolo Em seguida, pergunte a si mesmo o que acontece se duas pessoas fazem as mesmas ações muito rápido O que acontece se encadeiam dois outros eventos rapidamente O que eu faço com as mensagens que não lido ao mudar de estados Você verá que a complexidade cresce rapidamente Você pode encontrar uma solução semelhante Ao meu, possivelmente uma aposta Ter um deixe-me saber se este é o caso Não importa o resultado, é uma coisa muito interessante para trabalhar e nossos FSMs ainda são relativamente simples. Uma vez que você digerido tudo isso ou antes, se você é um leitor rebelde, você pode Vá para a próxima seção, onde implementamos o sistema de jogos Por agora você pode tomar uma pausa agradável café se você sentir vontade de fazê-lo. A primeira coisa que precisa ser feito para implementar o nosso protocolo com OTP s genfsm é criar a interface Lá Será 3 chamadores para o nosso módulo o jogador, o comportamento genfsm e FSM do outro jogador Nós só precisará exportar a função do jogador e funções genfsm, embora Isso é porque o outro FSM também será executado dentro do módulo tradefsm e pode acessá-los A partir de dentro. So essa é a nossa API Você pode ver Eu estou planejando ter algumas funções sendo simultaneamente síncrono e assíncrono Isso é principalmente porque queremos que o nosso cliente nos chamar de forma síncrona em alguns casos, mas o outro FSM pode fazê-lo de forma assíncrona Ter o Sincronização do cliente Ronous simplifica a nossa lógica um lote inteiro, limitando o número de mensagens contraditórias que podem ser enviadas uma após a outra Vamos chegar lá Vamos primeiro implementar a API pública real de acordo com o protocolo definido acima. Este é bastante padrão todas estas funções genfsm têm Foram cobertos antes, exceto start 3-4 e startlink 3-4 que eu acredito que você pode descobrir neste capítulo. Em seguida, vamos implementar o FSM para FSM funções Os primeiros têm a ver com configurações de comércio, quando queremos primeiro perguntar Outro usuário para se juntar a nós em um trade. The primeira função pede o pid outros, se quiserem o comércio, eo segundo é usado para responder de forma assíncrona, naturalmente. Podemos então escrever as funções para oferecer e cancelar ofertas de acordo com Nosso protocolo acima, isso é o que eles devem ser like. So, agora que temos ve estas chamadas feitas, precisamos nos concentrar no resto As chamadas restantes se referem a estar pronto ou não e lidar com o commit final Novamente, dado o nosso protocolo acima , Temos três chamadas ar Eyouready que pode ter as respostas notyet ou pronto. As únicas funções deixadas são aquelas que devem ser usadas por ambos os FSMs ao fazer o commit no estado pronto. Seu uso exato será descrito mais detalhadamente mais tarde, mas para agora, os nomes e O diagrama de estado de seqüência de antes deve ser suficiente No entanto, você ainda pode transcrevê-los para sua própria versão de tradefsm. Oh e há também a função de cortesia permitindo-nos avisar os outros FSM que cancelou o trade. We pode agora passar para o realmente Parte interessante o callbacks genfsm O primeiro callback é init 1 No nosso caso, vamos queremos cada FSM para manter um nome para o usuário que representa dessa forma, a nossa saída será mais agradável nos dados que mantém passando para si mesmo O que mais nós Queremos manter na memória No nosso caso, queremos o outro s pid, os itens que oferecemos e os itens que o outro oferece Nós também vamos adicionar a referência de um monitor para que nós sabemos para abortar se o outro morre e um de campo , Usado para fazer respostas atrasadas. E do init 1 só vamos nos preocupar com o nosso nome por agora Note que vamos começar no estado ocioso. Os próximos retornos de chamada a considerar seriam os próprios estados Até agora, eu descrevi as transições de estado e chamadas que podem ser feitas, Precisamos de uma maneira de certificar-se de que tudo vai bem Nós vamos escrever algumas funções de utilidade primeiro. E podemos começar com o estado ocioso Por uma questão de convenção, eu vou cobrir a versão assíncrona primeiro Este não deve se preocupar com nada, mas O outro jogador que pede um comércio dado o nosso próprio jogador, se você olhar para as funções API, irá usar uma chamada síncrona. Um monitor está configurado para permitir-nos a lidar com o outro morrer, e sua ref é armazenado nos dados FSM s Juntamente com os outros s pid, antes de passar para o estado idlewait Note que vamos relatar todos os eventos inesperados e ignorá-los por ficar no estado em que já estávamos Podemos ter algumas mensagens fora da banda aqui e ali que poderia ser o resultado De condições de corrida É geralmente seguro ignorá-los , Mas não podemos facilmente livrar-se deles É melhor não travar o FSM inteiro sobre essas mensagens desconhecidas, mas um pouco esperado. Quando nosso próprio cliente pede ao FSM para entrar em contato com outro jogador para um comércio, ele irá enviar um evento síncrono O retorno de chamada inativo 3 será needed. We proceder de uma forma semelhante à versão assíncrona, exceto que precisamos realmente perguntar ao outro lado se eles querem negociar com a gente ou não Você ll aviso que nós não responder ao cliente ainda This É porque não temos nada interessante para dizer, e queremos que o cliente bloqueado e esperando para o comércio a ser aceito antes de fazer qualquer coisa A resposta só será enviada se o outro lado aceita uma vez que estamos em idlewait. Quando estamos lá, temos Para lidar com o outro aceitar negociar eo outro pedindo para negociar o resultado de uma condição de corrida, como descrito no protocolo. Isso nos dá duas transições para o estado de negociação, mas lembre-se que nós devemos usar a resposta genfsm resposta 2 ao nosso cliente Para dizer que é oka Y para começar oferecendo artigos lá é também o caso de nosso cliente de FSM que aceita o comércio sugerido pelo outro party. Again, este move-se sobre ao estado do negotiate Aqui, nós devemos segurar consultas assíncronas para adicionar e remover os artigos que vêm ambos do Cliente e os outros FSM No entanto, ainda não decidimos como armazenar itens Porque eu sou um pouco preguiçoso e eu suponho que os usuários não t comércio que muitos itens, listas simples vai fazê-lo por enquanto No entanto, podemos mudar de opinião em um momento posterior , Por isso seria uma boa idéia para quebrar as operações item em suas próprias funções Adicionar as seguintes funções na parte inferior do arquivo com aviso 3 e inesperado 2.Simple, mas eles têm o papel de isolar as ações adicionando e removendo itens de seus Implementação usando listas Poderíamos facilmente mover para proplists, arrays ou qualquer estrutura de dados sem interromper o resto do código. Usando ambas as funções, podemos implementar oferecer e remover items. This é um aspecto feio de usar assíncrono bagunça Idades de ambos os lados Um conjunto de mensagem tem a forma de fazer e retrair, enquanto o outro tem fazer e desfazer Isto é inteiramente arbitrário e usado apenas para diferenciar entre o jogador de FSM comunicações e FSM-FSM comunicações Note que, De nosso próprio jogador, temos que dizer ao outro lado sobre as mudanças que estamos fazendo. Outra responsabilidade é lidar com a mensagem areyouready que mencionamos no protocolo Este é o último evento assíncrono para manipular no estado negotiate. Como descrito no Protocolo, sempre que não estamos no estado de espera e receber esta mensagem, temos de responder com notyet Também estavam fornecendo detalhes comerciais para o usuário para que uma decisão pode ser feita. Quando tal decisão é tomada eo usuário está pronto, o evento pronto Será enviado Este deve ser síncrono porque não queremos que o usuário continue modificando sua oferta, adicionando itens ao mesmo tempo reivindicando ele s ready. At neste ponto uma transição para o estado de espera deve ser feito Note que apenas esperando para o outro Não é interessante Eu salvei a variável De assim nós podemos usá-lo com resposta de genfsm 2 quando eu tenho algo dizer ao cliente. O estado de espera é uma besta engraçada Novos itens podem ser oferecidos e retraídos porque o outro usuário pode não estar pronto Faz sentido, então, para automaticamente reverter para o estado de negociação Seria ótimo ter grandes itens oferecidos a nós, apenas para o outro para removê-los e declarar-se pronto, roubando o nosso loot Voltando à negociação é uma boa decisão. Algo significativo e nós respondemos ao jogador com as coordenadas que armazenamos em O próximo conjunto de mensagens que precisamos nos preocupar são aqueles relacionados com a sincronização de ambos os FSMs para que eles possam mover para o estado pronto e confirmar o comércio Para este, devemos realmente Foco no protocolo definido anteriormente. As três mensagens que poderíamos ter são youyouready porque o outro usuário apenas declarou-se pronto, notyet porque pedimos o outro se ele estava pronto e ele não estava e pronto porque pedimos t Ele outro se ele estava pronto e ele era. Vamos começar com areyouready Lembre-se que no protocolo que disse que poderia haver uma condição de corrida escondida lá A única coisa que podemos fazer é enviar a mensagem pronta com já 1 e lidar com o resto Mais tarde. Nós estaremos presos esperando novamente, por isso não vale a pena responder ao nosso cliente ainda Similarmente, não vamos responder ao cliente quando o outro lado envia um notyet ao nosso convite. Por outro lado, se o outro está pronto, Nós enviamos uma mensagem extra pronto para o outro FSM, responda ao nosso próprio usuário e, em seguida, passar para o estado pronto. Você pode ter notado que eu usei acktrans 1 De fato, ambos os FSMs deve usá-lo Por que é isso Para entender isso temos Para começar a olhar para o que se passa no estado pronto. Quando no estado pronto, ambas as ações dos jogadores se tornam inúteis, exceto cancelamento Nós não vai cuidar de ofertas item novo Isso nos dá alguma liberdade Basicamente, ambos os FSMs podem falar livremente entre si sem se preocupar Sobre o resto do mundo. Isso nos permite implementar Bastardização de um commit de duas fases Para iniciar este commit sem que nenhum dos jogadores atue, precisamos de um evento para disparar uma ação dos FSMs O evento ack do acktrans 1 é usado para isso. Assim que estivermos no estado pronto, a mensagem É tratado e agiu sobre a transação pode begin. Two-fase comprometer requer comunicações síncronas, embora Isso significa que não podemos ter ambos FSMs iniciar a transação de uma só vez, porque eles vão acabar em deadlocked O segredo é encontrar uma maneira de decidir que um Máquina de estado finito deve iniciar o commit, enquanto o outro vai sentar e esperar ordens do primeiro one. It se torna que os engenheiros e cientistas de computador que projetou Erlang eram bem inteligente bem, nós sabíamos que já Os pids de qualquer processo pode ser Em comparação com os outros e ordenados Isso pode ser feito não importa quando o processo foi gerado, se ele ainda está vivo ou não, ou se ele vem de outra VM vamos ver mais sobre isso quando chegarmos em Erlang distribuído. Considando que dois Pids pode ser comparado e um será maior do que o outro, podemos escrever uma função prioridade 2 que terá dois pids e dizer um processo se ele foi eleito ou não. E chamando essa função, podemos ter um processo de iniciar a Commit e o outro seguindo as ordens. Aqui está o que isso nos dá quando incluído no estado pronto, depois de receber a mensagem ack. Esta grande expressão catch captura é o líder FSM decidir como o commit funciona Tanto askcommit 1 e docommit 1 são síncronos Este Permite que o líder FSM chamá-los livremente Você pode ver que o outro FSM só vai e esperar Ele receberá então as ordens do processo líder A primeira mensagem deve ser askcommit Isso é apenas para se certificar de que ambos os FSMs ainda estão lá nada de errado aconteceu, eles Re ambos dedicados a completar a tarefa. Uma vez que este é recebido, o principal processo irá pedir para confirmar a transação com docommit Isso é quando temos de cometer nossos dados. E uma vez que s feito, deixamos O FSM líder receberá ok Como uma resposta e vai saber para cometer em seu próprio fim depois Isso explica por que precisamos do grande tentar pegar se a resposta FSM morre ou o seu jogador cancela a transação, as chamadas síncronas vai falhar após um tempo limite O commit deve ser abortado neste caso Apenas para que você saiba, eu defini a função commit como segue. Pretty underwhelming, eh Em geral, não é possível fazer um commit seguro com apenas dois participantes um terceiro é geralmente necessário para julgar se ambos os jogadores fizeram tudo certo Se você fosse Para escrever uma verdadeira função de confirmação, deve entrar em contato com esse terceiro em nome de ambos os jogadores e, em seguida, fazer o seguro escrever para um banco de dados para eles ou reverter a troca inteira Nós won t ir em tais detalhes ea atual commit 1 função será O suficiente para as necessidades deste livro. Nós ainda não fizemos ainda não cobrimos dois tipos de eventos de um jogador de cancelamento do comércio e máquina de estado finito do outro jogador s falhando O primeiro pode ser tratado usando os callbacks han Dleevent 3 e handlesyncevent 4 Sempre que o outro usuário cancela, vamos receber uma notificação assíncrona. Quando o fazemos não devemos esquecer de dizer o outro antes de sair de nós mesmos. E voil O último evento para cuidar é quando o outro FSM vai para baixo Felizmente, tínhamos definido um monitor de volta no estado ocioso Podemos combinar sobre isso e reagir em conformidade. Note que mesmo se o cancelar ou desativar eventos acontecem enquanto estamos no commit, tudo deve ser seguro e ninguém deve obter seus itens roubados. Note que usamos io formato 2 para a maioria das nossas mensagens para permitir que os FSMs se comunicam com seus próprios clientes Em uma aplicação do mundo real, podemos querer algo mais flexível do que uma maneira de fazer é deixar o cliente enviar um Pid, ​​que 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