Skip to content

Instantly share code, notes, and snippets.

@eutkin
Created March 3, 2019 11:24
Show Gist options
  • Save eutkin/427c5995732ec0193ad9f1ddf1630134 to your computer and use it in GitHub Desktop.
Save eutkin/427c5995732ec0193ad9f1ddf1630134 to your computer and use it in GitHub Desktop.

Описание

Акторная модель

Система будет реализована на акторной модели, так как есть требования к масштабируемости, отказоустойчивости, а состояния система практически не имеет, поэтому акторная модель здесь отлично подойдет.

Фасад для бирж

trait ExchangeFacade {

  def balance(): Map[Currency, Balance]

  def placeOrder(symbol: Symbol, placement: Placement): Order

  def cancelOrder(symbol: Symbol, orderId: String)

  def getOpenOrders(symbol: Symbol) : Seq[Order]

  def checkOrderStatus(symbol: Symbol, orderId : String)

  def getTradesByOrder(orderId : String) : TradeHistory
  
  def getExchangeType : ExchangeType
}

trait ExchangeRouter {

    def selectExchange(exchangeType: ExchangeType) : ExchangeFacade
}

sealed trait Currency

type Symbol = (Currency, Currency)

case class Balance()

case class Placement(orderType: OrderType, price: BigDecimal, quantity: BigDecimal)

case class Order()

sealed trait OrderType

case object LimitOrder extends OrderType

case object MarketOrder extends OrderType

case class TradeHistory()

sealed trait ExchangeType

case object Binance
case object Bitfinex

Для выбора конкретного типа биржи будет использоваться паттерн Стратегия (ExchangeRouter).

Динамическая авторизация

Для авторизации можно использовать протокол oauth2 (или подобный, главное чтобы был внешний) auth provider.

  1. Клиент посылает команду вызова одной из функций (например, запрашивает баланс)
  2. Биржа редиректит его на один из auth provider (какой именно тип можно передавать в header'e запроса)
  3. Клиент авторизуется и получает токен, запрос с токеном возвращается на биржу
  4. Биржа запрашивает у выбранного auth provider'a про валидность токена. Если все ок, дергается функция.

Подобный алгоритм позволит иметь несколько внешних систем авторизаций, выбор из которых будет производиться по данным из запроса.

Например, у нас есть заказчики Х и Y. Они хотят иметь собственную систему авторизации. Они разворчивают AuthProviderX и AuthProviderY. В запросе от клиента в header'e передается источник запроса - X и Y. В зависимости от типа, клиент биржи редиректит на соответствующий AuthProvider и далее работает с ним во время выполнения запроса (проверяет валидность токена, к примеру)

Гео роутинг

  1. Проксирование

  2. Для реализации будет использованы акторы, которые развернуты в нужной стране (на облаках, либо на отдельном сервере). Для доступа к ним можно применить механизм remote actor, например, akka-remote. Либо другой механизм связи, но обязательно бизнес-логика должна быть реализована такой же кодовой базой.

В каждой реализации ExchangeFacade для конкретной биржы должно быть заинкапсулировано местонахождение (remote или local) актора. То есть при передаче команды актору клиента конкретной биржи мы не должны знать, где выполнится актор, на локальной машине или удаленной.

Хранение секретов

Секреты хранить в Vault By HashiCorp, для доступа обернуть в актор

Состав системы:

  • Набор внешних auth provider'ов как сервисов
  • модуль обработки web запросов
  • модуль роутинга по доступным биржам
  • набор модулей-реализаций для каждой из бирж
  • модуль гео роутинга
  • модуль хранения конфигураций (секретных или не очень)

Все модули представлены в виде акторов. Масштабируемость и расширения списка из-за свойств акторных моделей происходит довольно легко (при расширение усложняется только роутер между биржами и то, можно сделать через конфигурацию, тип биржки = адрес актора реализации).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment