UNPKG

ydb-sdk

Version:

Node.js bindings for working with YDB API over gRPC

157 lines (156 loc) 7.82 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.InternalTopicReadStream = void 0; const ydb_sdk_proto_1 = require("ydb-sdk-proto"); const events_1 = __importDefault(require("events")); const errors_1 = require("../../errors"); const symbols_1 = require("../symbols"); const add_credentials_to_metadata_1 = require("../../credentials/add-credentials-to-metadata"); class InternalTopicReadStream { constructor(ctx, topicService, // @ts-ignore logger) { this.topicService = topicService; this.logger = logger; this.events = new events_1.default(); this.logger.trace('%s: new TopicReadStreamWithEvents()', ctx); } ; async init(ctx, args) { this.logger.trace('%s: InternalTopicReadStream.init()', ctx); await this.topicService.updateMetadata(); this.readBidiStream = this.topicService.grpcServiceClient .makeBidiStreamRequest('/Ydb.Topic.V1.TopicService/StreamRead', (v) => ydb_sdk_proto_1.Ydb.Topic.StreamReadMessage.FromClient.encode(v).finish(), ydb_sdk_proto_1.Ydb.Topic.StreamReadMessage.FromServer.decode, this.topicService.metadata); //// Uncomment to see all events // const oldEmit = stream.emit; // stream.emit = ((...args) => { // console.info('read event:', args); // return oldEmit.apply(stream, args as unknown as ['readable']); // }) as typeof oldEmit; this.readBidiStream.on('data', (value) => { this.logger.trace('%s: TopicReadStreamWithEvents.on "data"', ctx); try { try { errors_1.YdbError.checkStatus(value); } catch (err) { this.events.emit('error', err); return; } if (value.readResponse) this.events.emit('readResponse', value.readResponse); else if (value.initResponse) { this.events.emit('initResponse', value.initResponse); } else if (value.commitOffsetResponse) this.events.emit('commitOffsetResponse', value.commitOffsetResponse); else if (value.partitionSessionStatusResponse) this.events.emit('partitionSessionStatusResponse', value.partitionSessionStatusResponse); else if (value.startPartitionSessionRequest) this.events.emit('startPartitionSessionRequest', value.startPartitionSessionRequest); else if (value.stopPartitionSessionRequest) this.events.emit('stopPartitionSessionRequest', value.stopPartitionSessionRequest); else if (value.updateTokenResponse) this.events.emit('updateTokenResponse', value.updateTokenResponse); } catch (err) { this.events.emit('error', err); } }); this.readBidiStream.on('error', (err) => { this.logger.trace('%s: TopicReadStreamWithEvents.on "error"', ctx); if (this.reasonForClose) { this.events.emit('end', err); } else { this.events.emit('error', errors_1.TransportError.convertToYdbError(err)); } }); this.initRequest(ctx, args); } initRequest(ctx, args) { this.logger.trace('%s: TopicReadStreamWithEvents.initRequest()', ctx); this.readBidiStream.write(ydb_sdk_proto_1.Ydb.Topic.StreamReadMessage.create({ initRequest: ydb_sdk_proto_1.Ydb.Topic.StreamReadMessage.InitRequest.create(args), })); } async readRequest(ctx, args) { this.logger.trace('%s: TopicReadStreamWithEvents.readRequest()', ctx); if (!this.readBidiStream) throw new Error('Stream is closed'); await this.updateToken(ctx); this.readBidiStream.write(ydb_sdk_proto_1.Ydb.Topic.StreamReadMessage.FromClient.create({ readRequest: ydb_sdk_proto_1.Ydb.Topic.StreamReadMessage.ReadRequest.create(args), })); } async commitOffsetRequest(ctx, args) { this.logger.trace('%s: TopicReadStreamWithEvents.commitOffsetRequest()', ctx); if (!this.readBidiStream) { const err = new Error('Inner stream where from the message was received is closed. The message needs to be re-processed.'); err.cause = symbols_1.innerStreamClosedSymbol; throw err; } await this.updateToken(ctx); this.readBidiStream.write(ydb_sdk_proto_1.Ydb.Topic.StreamReadMessage.FromClient.create({ commitOffsetRequest: ydb_sdk_proto_1.Ydb.Topic.StreamReadMessage.CommitOffsetRequest.create(args), })); } async partitionSessionStatusRequest(ctx, args) { this.logger.trace('%s: TopicReadStreamWithEvents.partitionSessionStatusRequest()', ctx); if (!this.readBidiStream) throw new Error('Stream is closed'); await this.updateToken(ctx); this.readBidiStream.write(ydb_sdk_proto_1.Ydb.Topic.StreamReadMessage.FromClient.create({ partitionSessionStatusRequest: ydb_sdk_proto_1.Ydb.Topic.StreamReadMessage.PartitionSessionStatusRequest.create(args), })); } async updateTokenRequest(ctx, args) { this.logger.trace('%s: TopicReadStreamWithEvents.updateTokenRequest()', ctx); if (!this.readBidiStream) throw new Error('Stream is closed'); await this.updateToken(ctx); this.readBidiStream.write(ydb_sdk_proto_1.Ydb.Topic.StreamReadMessage.FromClient.create({ updateTokenRequest: ydb_sdk_proto_1.Ydb.Topic.UpdateTokenRequest.create(args), })); // TODO: process response } async startPartitionSessionResponse(ctx, args) { this.logger.trace('%s: TopicReadStreamWithEvents.startPartitionSessionResponse()', ctx); if (!this.readBidiStream) throw new Error('Stream is closed'); await this.updateToken(ctx); this.readBidiStream.write(ydb_sdk_proto_1.Ydb.Topic.StreamReadMessage.FromClient.create({ startPartitionSessionResponse: ydb_sdk_proto_1.Ydb.Topic.StreamReadMessage.StartPartitionSessionResponse.create(args), })); } async stopPartitionSessionResponse(ctx, args) { this.logger.trace('%s: TopicReadStreamWithEvents.stopPartitionSessionResponse()', ctx); if (this.reasonForClose) throw new Error('Stream is not open'); await this.updateToken(ctx); this.readBidiStream.write(ydb_sdk_proto_1.Ydb.Topic.StreamReadMessage.FromClient.create({ stopPartitionSessionResponse: ydb_sdk_proto_1.Ydb.Topic.StreamReadMessage.StopPartitionSessionResponse.create(args), })); } close(ctx, error) { this.logger.trace('%s: TopicReadStreamWithEvents.close()', ctx); if (this.reasonForClose) throw new Error('Stream is not open'); this.reasonForClose = error; this.readBidiStream.cancel(); } async updateToken(ctx) { this.logger.trace('%s: TopicWriteStreamWithEvents.updateToken()', ctx); const oldVal = (0, add_credentials_to_metadata_1.getTokenFromMetadata)(this.topicService.metadata); this.topicService.updateMetadata(); const newVal = (0, add_credentials_to_metadata_1.getTokenFromMetadata)(this.topicService.metadata); if (newVal && oldVal !== newVal) await this.updateTokenRequest(ctx, { token: newVal }); } } exports.InternalTopicReadStream = InternalTopicReadStream;