diff options
Diffstat (limited to 'packages/0x.js/src/order_watcher/expiration_watcher.ts')
-rw-r--r-- | packages/0x.js/src/order_watcher/expiration_watcher.ts | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/packages/0x.js/src/order_watcher/expiration_watcher.ts b/packages/0x.js/src/order_watcher/expiration_watcher.ts new file mode 100644 index 000000000..1a9e9a418 --- /dev/null +++ b/packages/0x.js/src/order_watcher/expiration_watcher.ts @@ -0,0 +1,58 @@ +import * as _ from 'lodash'; +import {BigNumber} from 'bignumber.js'; +import {utils} from '../utils/utils'; +import {intervalUtils} from '../utils/interval_utils'; +import {SignedOrder} from '../types'; +import {Heap} from '../utils/heap'; +import {ZeroEx} from '../0x'; + +// Order prunning is very fast +const DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS = 50; + +/** + * This class includes all the functionality related to prunning expired orders + */ +export class ExpirationWatcher { + private orderHashHeapByExpiration: Heap<string>; + private expiration: {[orderHash: string]: BigNumber}; + private callbackIfExists?: (orderHash: string) => void; + private orderExpirationCheckingIntervalMs: number; + private orderExpirationCheckingIntervalIdIfExists?: NodeJS.Timer; + constructor(orderExpirationCheckingIntervalMs?: number) { + this.orderExpirationCheckingIntervalMs = orderExpirationCheckingIntervalMs || + DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS; + this.expiration = {}; + const scoreFunction = ((orderHash: string) => { + return this.expiration[orderHash].toNumber(); + }).bind(this); + this.orderHashHeapByExpiration = new Heap(scoreFunction); + } + public subscribe(callback: (orderHash: string) => void): void { + this.callbackIfExists = callback; + this.orderExpirationCheckingIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval( + this.pruneExpiredOrders.bind(this), this.orderExpirationCheckingIntervalMs, + ); + } + public unsubscribe(): void { + intervalUtils.clearAsyncExcludingInterval(this.orderExpirationCheckingIntervalIdIfExists as NodeJS.Timer); + delete this.callbackIfExists; + } + public addOrder(orderHash: string, expirationUnixTimestampSec: BigNumber): void { + this.expiration[orderHash] = expirationUnixTimestampSec; + // We don't remove hashes on order remove because it's slow (linear). + // We just skip them later if the order was already removed from the order watcher. + this.orderHashHeapByExpiration.push(orderHash); + } + private pruneExpiredOrders(): void { + const currentUnixTimestampSec = utils.getCurrentUnixTimestamp(); + while ( + this.orderHashHeapByExpiration.size() !== 0 && + this.expiration[this.orderHashHeapByExpiration.head()].lessThan(currentUnixTimestampSec) && + !_.isUndefined(this.callbackIfExists) + ) { + const orderHash = this.orderHashHeapByExpiration.pop(); + delete this.expiration[orderHash]; + this.callbackIfExists(orderHash); + } + } +} |