UNPKG

jspurefix

Version:
149 lines (125 loc) 5.17 kB
import { ElasticBuffer } from '../buffer' import moment = require('moment') export enum SessionState { Connected = 1, PeerLoggedOn = 2, PeerLogonRejected = 3, WaitingLogoutConfirm = 4, ConfirmingLogout = 5, Stopped = 6 } export enum TickAction { Nothing = 1, Heartbeat = 2, TestRequest = 3, TerminateOnError = 4, WaitLogoutConfirmExpired = 5, Stop = 6 } export class FixSessionState { public nextTickAction: TickAction = TickAction.Nothing public lastReceivedAt: Date = null public LastSentAt: Date = null public lastTestRequestAt: Date = null public logoutSentAt: Date = null public now: Date = new Date() public compId: string = '' public peerCompId: string = '' public peerHeartBeatSecs: number = 0 public lastPeerMsgSeqNum: number = 0 private secondsSinceLogoutSent: number = -1 private secondsSinceSent: number = -1 private secondsSinceReceive: number = -1 public constructor (public readonly heartBeat: number, public state: SessionState = SessionState.Connected, public readonly waitLogoutConfirmSeconds: number = 5, public readonly stopSeconds: number = 2) { } private static dateAsString (d: Date) { if (!d) { return 'null' } return moment(d).format('HH:mm:ss.SSS') } public toString (): string { const buffer = new ElasticBuffer(1024) buffer.writeString(`compId = ${this.compId}, `) buffer.writeString(`heartBeat = ${this.heartBeat}, `) buffer.writeString(`state = ${this.state}, `) buffer.writeString(`nextTickAction = ${this.nextTickAction}, `) buffer.writeString(`now = ${FixSessionState.dateAsString(this.now)}, `) buffer.writeString(`timeToDie = ${this.timeToDie()}, `) buffer.writeString(`timeToHeartbeat = ${this.timeToHeartbeat()}, `) buffer.writeString(`timeToTerminate = ${this.timeToTerminate()}, `) buffer.writeString(`timeToTestRequest = ${this.timeToTestRequest()}, `) buffer.writeString(`lastReceivedAt = ${FixSessionState.dateAsString(this.lastReceivedAt)}, `) buffer.writeString(`LastSentAt = ${FixSessionState.dateAsString(this.LastSentAt)}, `) buffer.writeString(`lastTestRequestAt = ${FixSessionState.dateAsString(this.lastTestRequestAt)}, `) buffer.writeString(`logoutSentAt = ${FixSessionState.dateAsString(this.logoutSentAt)}, `) buffer.writeString(`peerHeartBeatSecs = ${this.peerHeartBeatSecs}, `) buffer.writeString(`peerCompId = ${this.peerCompId}, `) buffer.writeString(`lastPeerMsgSeqNum = ${this.lastPeerMsgSeqNum}, `) buffer.writeString(`secondsSinceLogoutSent = ${this.secondsSinceLogoutSent}, `) buffer.writeString(`secondsSinceSent = ${this.secondsSinceSent}, `) buffer.writeString(`secondsSinceReceive = ${this.secondsSinceReceive}`) return buffer.toString() } public calcAction (now: Date): TickAction { this.now = now this.calcState() switch (this.state) { case SessionState.PeerLogonRejected: { if (this.secondsSinceSent >= this.stopSeconds) { this.nextTickAction = TickAction.Stop } break } case SessionState.WaitingLogoutConfirm: case SessionState.ConfirmingLogout: { if (this.timeToDie()) { this.nextTickAction = TickAction.Stop } break } case SessionState.PeerLoggedOn: { if (this.timeToHeartbeat()) { // have not sent anything for heartbeat period so let other side know still alive. this.nextTickAction = TickAction.Heartbeat } else { // console.log(`${application.name}: secondsSinceSent = ${secondsSinceSent} secondsSinceReceive = ${secondsSinceReceive}`) if (this.timeToTerminate()) { this.nextTickAction = TickAction.TerminateOnError } else if (this.timeToTestRequest()) { if (!this.lastTestRequestAt) { // not received anything from peer this.nextTickAction = TickAction.TestRequest this.lastTestRequestAt = this.now } } } break } } return this.nextTickAction } public timeToDie (): boolean { return this.secondsSinceLogoutSent > this.waitLogoutConfirmSeconds || this.secondsSinceLogoutSent > this.stopSeconds } public timeToHeartbeat (): boolean { return this.secondsSinceSent >= this.heartBeat } public timeToTerminate (): boolean { return this.secondsSinceReceive >= 2.5 * this.peerHeartBeatSecs } public timeToTestRequest (): boolean { return this.secondsSinceReceive >= 1.5 * this.peerHeartBeatSecs } private calcState (): void { const time = this.now.getTime() this.nextTickAction = TickAction.Nothing this.secondsSinceLogoutSent = this.logoutSentAt ? (time - this.logoutSentAt.getTime()) / 1000 : -1 this.secondsSinceSent = (time - this.LastSentAt.getTime()) / 1000 this.secondsSinceReceive = (time - this.lastReceivedAt.getTime()) / 1000 } }