UNPKG

@kevin_men/websocket

Version:

TDengine Connector for nodejs and browser using WebSocket.

317 lines (316 loc) 12.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WsConsumer = void 0; const config_1 = require("./config"); const constant_1 = require("./constant"); const wsClient_1 = require("../client/wsClient"); const wsError_1 = require("../common/wsError"); const tmqResponse_1 = require("./tmqResponse"); const reqid_1 = require("../common/reqid"); const log_1 = __importDefault(require("../common/log")); class WsConsumer { constructor(wsConfig) { this._wsConfig = new config_1.TmqConfig(wsConfig); log_1.default.debug(this._wsConfig); this._wsClient = new wsClient_1.WsClient(this._wsConfig.url, this._wsConfig.timeout); } async init() { await this._wsClient.ready(); return this; } static async newConsumer(wsConfig) { if (wsConfig.size == 0 || !wsConfig.get(constant_1.TMQConstants.WS_URL)) { throw new wsError_1.WebSocketInterfaceError(wsError_1.ErrorCode.ERR_INVALID_URL, 'invalid url, password or username needed.'); } let wsConsumer = new WsConsumer(wsConfig); return await wsConsumer.init(); } async subscribe(topics, reqId) { if (!topics || topics.length == 0) { throw new wsError_1.TaosResultError(wsError_1.ErrorCode.ERR_INVALID_PARAMS, 'WsTmq Subscribe params is error!'); } let queryMsg = { action: constant_1.TMQMessageType.Subscribe, args: { req_id: reqid_1.ReqId.getReqID(reqId), user: this._wsConfig.user, password: this._wsConfig.password, group_id: this._wsConfig.group_id, client_id: this._wsConfig.client_id, topics: topics, offset_rest: this._wsConfig.offset_rest, auto_commit: this._wsConfig.auto_commit, auto_commit_interval_ms: this._wsConfig.auto_commit_interval_ms }, }; this._topics = topics; return await this._wsClient.exec(JSON.stringify(queryMsg)); } async unsubscribe(reqId) { let queryMsg = { action: constant_1.TMQMessageType.Unsubscribe, args: { req_id: reqid_1.ReqId.getReqID(reqId), }, }; return await this._wsClient.exec(JSON.stringify(queryMsg)); } async poll(timeoutMs, reqId) { if (this._wsConfig.auto_commit) { if (this._commitTime) { let currTime = new Date().getTime(); let diff = Math.abs(currTime - this._commitTime); if (diff >= this._wsConfig.auto_commit_interval_ms) { await this.doCommit(); this._commitTime = new Date().getTime(); } } else { this._commitTime = new Date().getTime(); } } return await this.pollData(timeoutMs, reqId); } async subscription(reqId) { let queryMsg = { action: constant_1.TMQMessageType.ListTopics, args: { req_id: reqid_1.ReqId.getReqID(reqId), }, }; let resp = await this._wsClient.exec(JSON.stringify(queryMsg), false); return new tmqResponse_1.SubscriptionResp(resp).topics; } async commit(reqId) { await this.doCommit(reqId); return await this.assignment(); } async doCommit(reqId) { let queryMsg = { action: constant_1.TMQMessageType.Commit, args: { req_id: reqid_1.ReqId.getReqID(reqId), message_id: 0 }, }; await this._wsClient.exec(JSON.stringify(queryMsg)); } async committed(partitions, reqId) { if (!partitions || partitions.length == 0) { throw new wsError_1.TaosResultError(wsError_1.ErrorCode.ERR_INVALID_PARAMS, 'WsTmq Positions params is error!'); } let offsets = new Array(partitions.length); for (let i = 0; i < partitions.length; i++) { offsets[i] = { topic: partitions[i].topic, vgroup_id: partitions[i].vgroup_id }; offsets[i].vgroup_id = partitions[i].vgroup_id; } let queryMsg = { action: constant_1.TMQMessageType.Committed, args: { req_id: reqid_1.ReqId.getReqID(reqId), topic_vgroup_ids: offsets }, }; let resp = await this._wsClient.exec(JSON.stringify(queryMsg), false); return new tmqResponse_1.CommittedResp(resp).setTopicPartitions(offsets); } async commitOffsets(partitions) { if (!partitions || partitions.length == 0) { throw new wsError_1.TaosResultError(wsError_1.ErrorCode.ERR_INVALID_PARAMS, 'WsTmq CommitOffsets params is error!'); } const allp = []; partitions.forEach(e => { allp.push(this.commitOffset(e)); }); await Promise.all(allp); return await this.committed(partitions); } async commitOffset(partition, reqId) { if (!partition) { throw new wsError_1.TaosResultError(wsError_1.ErrorCode.ERR_INVALID_PARAMS, 'WsTmq CommitOffsets params is error!'); } let queryMsg = { action: constant_1.TMQMessageType.CommitOffset, args: { req_id: reqid_1.ReqId.getReqID(reqId), vgroup_id: partition.vgroup_id, topic: partition.topic, offset: partition.offset, }, }; return await this._wsClient.exec(JSON.stringify(queryMsg)); } async positions(partitions, reqId) { if (!partitions || partitions.length == 0) { throw new wsError_1.TaosResultError(wsError_1.ErrorCode.ERR_INVALID_PARAMS, 'WsTmq Positions params is error!'); } let offsets = new Array(partitions.length); for (let i = 0; i < partitions.length; i++) { offsets[i] = { topic: partitions[i].topic, vgroup_id: partitions[i].vgroup_id }; offsets[i].vgroup_id = partitions[i].vgroup_id; } let queryMsg = { action: constant_1.TMQMessageType.Position, args: { req_id: reqid_1.ReqId.getReqID(reqId), topic_vgroup_ids: offsets }, }; let resp = await this._wsClient.exec(JSON.stringify(queryMsg), false); return new tmqResponse_1.PartitionsResp(resp).setTopicPartitions(offsets); } async seek(partition, reqId) { if (!partition) { throw new wsError_1.TaosResultError(wsError_1.ErrorCode.ERR_INVALID_PARAMS, 'WsTmq Seek params is error!'); } let queryMsg = { action: constant_1.TMQMessageType.Seek, args: { req_id: reqid_1.ReqId.getReqID(reqId), vgroup_id: partition.vgroup_id, topic: partition.topic, offset: partition.offset, }, }; return await this._wsClient.exec(JSON.stringify(queryMsg)); } async seekToBeginning(partitions) { if (!partitions || partitions.length == 0) { throw new wsError_1.TaosResultError(wsError_1.ErrorCode.ERR_INVALID_PARAMS, 'WsTmq SeekToBeginning params is error!'); } return await this.seekToBeginOrEnd(partitions); } async seekToEnd(partitions) { if (!partitions || partitions.length == 0) { throw new wsError_1.TaosResultError(wsError_1.ErrorCode.ERR_INVALID_PARAMS, 'WsTmq SeekToEnd params is error!'); } return await this.seekToBeginOrEnd(partitions, false); } async close() { await this._wsClient.close(); } async fetch(pollResp) { let fetchMsg = { action: 'fetch', args: { req_id: reqid_1.ReqId.getReqID(), message_id: pollResp.message_id, }, }; let jsonStr = JSON.stringify(fetchMsg); log_1.default.debug('[wsQueryInterface.fetch.fetchMsg]===>' + jsonStr); let result = await this._wsClient.exec(jsonStr, false); return new tmqResponse_1.WsTmqQueryResponse(result); } async fetchBlockData(fetchResponse, taosResult) { let fetchMsg = { action: 'fetch_block', args: { req_id: fetchResponse.req_id, message_id: fetchResponse.message_id, }, }; let jsonStr = JSON.stringify(fetchMsg); log_1.default.debug('[wsQueryInterface.fetch.fetchMsg]===>' + jsonStr); let result = await this._wsClient.sendMsg(jsonStr); (0, tmqResponse_1.parseTmqBlock)(fetchResponse.rows, new tmqResponse_1.WSTmqFetchBlockResponse(result), taosResult); return taosResult; } async pollData(timeoutMs, reqId) { let queryMsg = { action: constant_1.TMQMessageType.Poll, args: { req_id: reqid_1.ReqId.getReqID(reqId), blocking_time: timeoutMs }, }; var taosResults = new Map(); let resp = await this._wsClient.exec(JSON.stringify(queryMsg), false); let pollResp = new tmqResponse_1.WsPollResponse(resp); if (!pollResp.have_message || pollResp.message_type != constant_1.TMQMessageType.ResDataType) { return taosResults; } while (true) { let fetchResp = await this.fetch(pollResp); if (fetchResp.completed || fetchResp.rows == 0) { break; } let taosResult = taosResults.get(pollResp.topic + pollResp.vgroup_id); if (taosResult == null) { taosResult = new tmqResponse_1.TaosTmqResult(fetchResp, pollResp); taosResults.set(pollResp.topic + pollResp.vgroup_id, taosResult); } else { taosResult.setRowsAndTime(fetchResp.rows); } await this.fetchBlockData(fetchResp, taosResult); } return taosResults; } async sendAssignmentReq(topic) { let queryMsg = { action: constant_1.TMQMessageType.GetTopicAssignment, args: { req_id: reqid_1.ReqId.getReqID(), topic: topic } }; let resp = await this._wsClient.exec(JSON.stringify(queryMsg), false); let assignmentInfo = new tmqResponse_1.AssignmentResp(resp, queryMsg.args.topic); return assignmentInfo.topicPartition; } async assignment(topics) { if (!topics || topics.length == 0) { topics = this._topics; } let topicPartitions = []; if (topics && topics.length > 0) { const allp = []; for (let i in topics) { allp.push(this.sendAssignmentReq(topics[i])); } let result = await Promise.all(allp); result.forEach(e => { topicPartitions.push(...e); }); } return topicPartitions; } async seekToBeginOrEnd(partitions, bBegin = true) { let topics = []; partitions.forEach(e => { topics.push(e.topic); }); let topicPartitions = await this.assignment(topics); let itemMap = topicPartitions.reduce((map, obj) => { map.set(obj.topic + '_' + obj.vgroup_id, obj); return map; }, new Map()); const allp = []; for (let i in partitions) { if (itemMap.has(partitions[i].topic + '_' + partitions[i].vgroup_id)) { let topicPartition = itemMap.get(partitions[i].topic + '_' + partitions[i].vgroup_id); if (topicPartition) { if (bBegin) { topicPartition.offset = topicPartition.begin; } else { topicPartition.offset = topicPartition.end; } allp.push(this.seek(topicPartition)); } } } await Promise.all(allp); } } exports.WsConsumer = WsConsumer;