Hola gente!
Mauro, interesante tema! Fui a leer tu problema/tema en
Hace unos anios conoci a @ashemi, que fue el arquitecto de un sistema de etrade (de acciones creo) en tiempo real. No tengo enlaces ahora, fue hace como una decada. El usaba (estoy recordando, no estoy seguro) un Blackboard, un pizarron donde se anotaban los nuevos hechos, y agentes que los examinaban. Ver
Pero me parece mas complejo que lo necesitas ahora. Un contexto
For example, consider a financial application that integrates trading tools, portfolio management applications, modeling and risk analysis tools, trend indicators, and tickers. Market activity causes interaction between these systems. For example, a trading system communicates the completion of a sell transaction by sending a message to all other trading applications. The trading system could have individual connections to each trading application. This works well for a few applications, but becomes a burden as the number of applications increases. Managing the addition or removal of trading applications should not interfere with processing trades.
Ahi mencionan related patterns:
see the following related patterns:
- Publish/Subscribe. This pattern helps keep cooperating systems synchronized by one-way propagation of messages; one publisher sends a message to any number of intended subscribers.
- Message Bus Architecture [Hohpe04]. This pattern revolves around a messaging infrastructure, and it relies on a canonical data model and a common command set that is mentioned earlier in "Liabilities."
- Blackboard [Buschmann96]. The Blackboard pattern describes a shared storage area that the components of the pattern use to communicate. Consumer components monitor the blackboard and grab the data that matches their interest. Producers put their output on the blackboard so that it becomes available to the others. Typically, integration applications such as rule engines and expert systems use this pattern.
Donde usan Eso debio ser el contexto de @ashemi, mas o menos.
Para lo tuyo, creo que debe haber algo mas simple. Primero, no sabria como calcular lo de profit/loss, equity, EN TIEMPO REAL. No se cuanto involucra eso. Un simple calculo? Una llamada a tres web services y 4 bases de datos?
(Agregado: mas abajo tengo codigo Node.js, en esa tecnologia, podria llegar a lanzar esas llamadas externas sin alterar tanto el proceso principal, no se si se acerca a lo que consideras real time)
Para el segundo punto que requieres, el de los triggers, haria una especie de pub/sub (desconozco el estado del arte de ahora, y la terminologia exacta). Alguien publicaria ordenes (de compra, venta) y los triggers dispararian mensajes a los suscriptores del trigger. Pero seria algo asi, en un Javascript/Node.js seudocodeado:
(disculpa que use esta notacion, no sabria como hacerlo en Ruby)
ordenes.on('neworder', function(neworder) {
triggers.forEach(function(trigger) {
if (trigger.satisfiedBy(neworder))
trigger.emit('neworder', neworder);
});
});
El tema es: cuanto cuesta el "satisfiedBy"? Deberia ser algo que ya tenga todo preparado, que no tenga que bailarse la conga. Si no fuera el caso, lo haria de manera asincronica, pasando un callback a ejecutar cuando se termine de calcular el satisfiedBy
trigger.satisfy(neworder, function () { trigger.emit('neworder', neworder); });
se puede simplificar, si el callback siempre es el mismo (el mismo codigo), ponerlo dentro del satisfy y listo.
Luego, los suscriptores a los triggers:
trigger.on('neworder', function () {
// bailate la conga, pero usando IO asincronica para no parar el proceso principal
});
Antes que me olvide, decia que no conocia el estado del arte y la terminologia actual de pub/sub (lo mio es escribir desde scratch, usando TDD ;-). Pero ver que Redis tiene un PUB SUB
pero vean que lo hace por pattern matching. Es decir, puedo poner (un codigo Lua?) un predicado que diga algo como: si la orden es de China, y es de soja para comprar, y el precio es > X, y esta lloviendo en Australia, entonces vendo.
Por eso prefiero codificar todo lo de arriba que mencione, paso a paso, usando TDD, para no adoptar una tecnologia que parece solucionar el problema, pero que luego, con casos de uso nuevos, me va a complicar todo.
Ah! Yo sabia que tenia algo programado... ;-)... tengo Pub/Sub en SimpleBus, JavaScript/Node.js, ver los test:
Veo ahi (me habia olvidado ;-) que tengo suscripcion a todos los mensajes, suscripcion by example, y suscription por cumplir un predicado.
Supongo que podes hacerlo todo en Ruby, solo que no sabria como ponerte codigo ahora.
En algun momento, plantearia:
- Tener varios nodos/maquinas ejecutando.
- Cada maquina puede registrar subscripciones, y avisarles a las demas
- Todas pueden recibir nuevos mensajes (ordenes en tu caso)
- Cada maquina atiende a sus subscriptores, y si una order cumple con un predicado/filtro de otra maquina, se la envia
No es dificil hacerlo en Node (ojala pudiera escribirte codigo Ruby ;-). Eso es lo que quiero para SimpleBus. En JavaScript/Node.js, las funciones predicado, si son simples y no tienen free variables, las puedo serializar y ejecutar en otras maquinas, con apenas unas lineas.
En todo caso, siempre podes llamar y comunicarte a Node con Ruby.
Ahora estoy luchando con el Efecto Coto:
pero seria interesante poner un sample de SimpleBus que contemple tu escenario: un nodo, y luego, un ejemplo distribuido.
Enlaces que pueden resultar interesantes para el tema:
Supongo que los rubystas de la lista mencionaran
El tema de event io se usa, principalmente, para que lo que tengas que hacer en tu sistema (llamar al sistema de compra, etc... ) que involcre entrada/salida, no paralice tu logica principal. Pienso que hoy, si necesitas resolver tu problema, no vas a zafar de llegar a usarlo en algun momento.
Nos leemos!
Angel "Java" Lopez
@ajlopez
github:ajlopez