import { WSClient } from '@0x/mesh-rpc-client' ; import * as _ from 'lodash' ; import { getDBConnection } from '../db_connection' ; import { MeshUtils } from '../mesh_utils' ; import { SignedOrderModel } from '../models/SignedOrderModel' ; import { APIOrderWithMetaData , OrderWatcherLifeCycleEvents } from '../types' ; import { deserializeOrder , serializeOrder } from './orderbook_utils' ; const d = require ( 'debug' ) ( 'orderbook' ) ; export class OrderWatcherService { private readonly _meshClient : WSClient ; private static async _onOrderLifeCycleEventAsync ( lifecycleEvent , orders ) { if ( orders . length <= 0 ) { return ; } const connection = getDBConnection ( ) ; switch ( lifecycleEvent ) { case OrderWatcherLifeCycleEvents . Updated : case OrderWatcherLifeCycleEvents . Added : { const signedOrdersModel = orders . map ( o => serializeOrder ( o ) ) ; await connection . manager . save ( signedOrdersModel , { chunk : 900 } ) ; break ; } case OrderWatcherLifeCycleEvents . Removed : { const orderHashes = orders . map ( o => o . metaData . orderHash ) ; const chunks = _ . chunk ( orderHashes , 999 ) ; for ( const chunk of chunks ) { await connection . manager . delete ( SignedOrderModel , chunk ) ; } break ; } default : } } constructor ( meshClient ) { this . _meshClient = meshClient ; void this . _meshClient . subscribeToOrdersAsync ( async ( orders ) => { const { added , removed , updated } = MeshUtils . calculateAddedRemovedUpdated ( orders ) ; await OrderWatcherService . _onOrderLifeCycleEventAsync ( OrderWatcherLifeCycleEvents . Removed , removed ) ; await OrderWatcherService . _onOrderLifeCycleEventAsync ( OrderWatcherLifeCycleEvents . Updated , updated ) ; await OrderWatcherService . _onOrderLifeCycleEventAsync ( OrderWatcherLifeCycleEvents . Added , added ) ; } ) ; this . _meshClient . onReconnected ( async ( ) => { d ( 'Reconnecting to Mesh' ) ; await this . syncOrderbookAsync ( ) ; } ) ; } public async syncOrderbookAsync ( ) { d ( 'SYNC orderbook with Mesh' ) ; const connection = getDBConnection ( ) ; const signedOrderModels = ( await connection . manager . find ( SignedOrderModel ) ) as Array < Required < SignedOrderModel > > ; const signedOrders = signedOrderModels . map ( deserializeOrder ) ; const orders = await this . _meshClient . getOrdersAsync ( ) ; const { accepted , rejected } = await MeshUtils . addOrdersToMeshAsync ( this . _meshClient , signedOrders ) ; d ( `SYNC ${ rejected . length } rejected ${ accepted . length } accepted ${ signedOrders . length } sent` ) ; if ( rejected . length > 0 ) { await OrderWatcherService . _onOrderLifeCycleEventAsync ( OrderWatcherLifeCycleEvents . Removed , MeshUtils . orderInfosToApiOrders ( rejected ) ) ; } if ( orders . length > 0 ) { await OrderWatcherService . _onOrderLifeCycleEventAsync ( OrderWatcherLifeCycleEvents . Added , MeshUtils . orderInfosToApiOrders ( orders ) ) ; } d ( 'SYNC complete' ) ; } }