UNPKG

fox-wamp

Version:

Web Application Message Router/Server WAMP/MQTT

145 lines (126 loc) 4.22 kB
'use strict' const { keyId, MakeId } = require("../allot/makeid") class HistorySegment { constructor () { this.content = [] } addEvent (event) { this.content.push(event) } count () { return this.content.length } } class EntrySession { constructor (wampSession, syncMass, historyDb, gateId, pubResult) { this.wampSession = wampSession this.stackAdvanceSegment = [] this.curAdvanceSegment = undefined this.syncMass = syncMass this.historyDb = historyDb this.gateId = gateId this.pubResult = pubResult this.segmentToWrite = new Map() this.isEventSource = false wampSession.subscribe('beginSegment', (args, kwargs, opts) => { const advanceSegment = args[0].advanceSegment this.queueSync(advanceSegment) wampSession.publish('beginSegmentAccepted', [{advanceSegment: advanceSegment}]) }) wampSession.subscribe('saveHistory', (args, kwargs, opts) => { console.log("saveHistory", args, kwargs) this.delayEvent(kwargs) }) wampSession.subscribe('eventSourceLock', (args, kwargs, opts) => { if (kwargs.pid == process.pid) { console.log('gate '+this.gateId + ": eventSource in "+this.isEventSource, args, kwargs, opts) } }, {retained: true}) wampSession.publish( 'eventSourceLock', [], { pid: process.pid }, { acknowledge: true, retain: true, when: null, will: null, watch: true, exclude_me: false } ).then((result) => { console.log('GATE:'+this.gateId+': use that db as event source', result) this.isEventSource = true }) } delayEvent (event) { let segment = this.segmentToWrite.get(event.advanceId.segment) if (!segment) { segment = new HistorySegment() this.segmentToWrite.set(event.advanceId.segment, segment) } segment.addEvent(event) if (segment.count() !== event.advanceId.id) { console.error('serment position is not equal', segment.count(), event.advanceId.id) } } sendToMakeSegment (advanceSegment) { console.log('sendToMakeSegment on SYNC advanceSegment[', advanceSegment, '] to count:', this.syncMass.size) for (let [,ss] of this.syncMass) { ss.publish('makeSegmentId', [], {advanceSegment, step: 2}) } } checkLine () { if (this.curAdvanceSegment) { return false } this.curAdvanceSegment = this.stackAdvanceSegment.shift() if (this.curAdvanceSegment) { this.sendToMakeSegment(this.curAdvanceSegment) return true } return false } queueSync (advanceSegment) { this.stackAdvanceSegment.push(advanceSegment) return this.checkLine() } publishSegment (segment) { if (this.isEventSource) { for (const event of segment.content) { console.log('publishSegment-dispatchEvent', event) this.wampSession.publish('dispatchEvent', [], { realm: event.realm, data: event.data, uri: event.uri, opt: event.opt, sid: event.sid, qid: event.qid }) } } } commitSegment (advanceSegment, segmentId) { // check is advanceSegment of mine session if (this.curAdvanceSegment === advanceSegment) { console.log("dbSaveSegment", advanceSegment, segmentId) let segment = this.segmentToWrite.get(advanceSegment) if (segment) { this.segmentToWrite.delete(advanceSegment) let effectId = this.dbSaveSegment(segment, segmentId) this.pubResult(advanceSegment, segment, effectId) } else { console.error("advanceSegment not found in segments [", advanceSegment, "]") } this.curAdvanceSegment = undefined return this.checkLine() } return false } // todo: wait for promise in saveEventHistory dbSaveSegment (segment, segmentId) { let result = [] const makeId = new MakeId((a) => a) makeId.update(segmentId.dt + keyId(segmentId.id)) for (let row of segment.content) { let id = makeId.makeIdStr() this.historyDb.saveEventHistory(id, row.realm, row.uri, row.data, row.opt) result.push(id) // keep event position in result array } return result } } exports.EntrySession = EntrySession