|
@@ -7,14 +7,21 @@ export class BufferService {
|
|
private bufferIdentifier!: string
|
|
private bufferIdentifier!: string
|
|
private messageStream: Subject<Message>;
|
|
private messageStream: Subject<Message>;
|
|
private connectionState: BehaviorSubject<ConnectionState>;
|
|
private connectionState: BehaviorSubject<ConnectionState>;
|
|
- private messageBuffer: Message[] = [];
|
|
|
|
|
|
+ private messageBuffered: Message[] = [];
|
|
private messageModel!: Model<Message>
|
|
private messageModel!: Model<Message>
|
|
private readonly dbUrl!: string
|
|
private readonly dbUrl!: string
|
|
|
|
+ private bufferLimit!: number
|
|
constructor(
|
|
constructor(
|
|
messageFromApp: Subject<Message>,
|
|
messageFromApp: Subject<Message>,
|
|
connectionStateSubject: BehaviorSubject<ConnectionState>,
|
|
connectionStateSubject: BehaviorSubject<ConnectionState>,
|
|
- dbName: string
|
|
|
|
|
|
+ dbName: string,
|
|
|
|
+ bufferLimit?: number
|
|
) {
|
|
) {
|
|
|
|
+ if (bufferLimit) {
|
|
|
|
+ this.bufferLimit = bufferLimit
|
|
|
|
+ } else {
|
|
|
|
+ this.bufferLimit = 10000 // default buffer limit
|
|
|
|
+ }
|
|
this.bufferIdentifier = dbName
|
|
this.bufferIdentifier = dbName
|
|
this.messageStream = messageFromApp;
|
|
this.messageStream = messageFromApp;
|
|
this.connectionState = connectionStateSubject;
|
|
this.connectionState = connectionStateSubject;
|
|
@@ -80,6 +87,9 @@ export class BufferService {
|
|
}
|
|
}
|
|
|
|
|
|
private handleIncomingMessage(message: any): void {
|
|
private handleIncomingMessage(message: any): void {
|
|
|
|
+ if (this.connectionState.getValue().status === `LIMIT_EXCEEDED`) {
|
|
|
|
+ // do nothing... Let handleConnectionStateChanges deal with this state
|
|
|
|
+ }
|
|
if (this.connectionState.getValue().status === "BUFFER") {
|
|
if (this.connectionState.getValue().status === "BUFFER") {
|
|
this.bufferMessage(message);
|
|
this.bufferMessage(message);
|
|
}
|
|
}
|
|
@@ -93,6 +103,16 @@ export class BufferService {
|
|
|
|
|
|
private handleConnectionStateChanges(state: ConnectionState): void {
|
|
private handleConnectionStateChanges(state: ConnectionState): void {
|
|
console.log(`${this.bufferIdentifier}: ${this.connectionState.getValue().status}`);
|
|
console.log(`${this.bufferIdentifier}: ${this.connectionState.getValue().status}`);
|
|
|
|
+ if (state.status === `LIMIT_EXCEEDED`) {
|
|
|
|
+ console.log(`Limit exceed. Clearing buffered messages...`)
|
|
|
|
+ let message: Message = {
|
|
|
|
+ id: `test`,
|
|
|
|
+ message: `Limit exceed. Please take care. Buffer Service Out!`
|
|
|
|
+ }
|
|
|
|
+ this.messageStream.next(message)
|
|
|
|
+ // this.messageStream.unsubscribe() //destroy existing subscription
|
|
|
|
+ this.messageBuffered = []
|
|
|
|
+ }
|
|
if (state.status === "BUFFER") {
|
|
if (state.status === "BUFFER") {
|
|
if (state.payload && typeof state.payload !== "string") {
|
|
if (state.payload && typeof state.payload !== "string") {
|
|
this.bufferMessage(state.payload); // Buffer the last message immediately
|
|
this.bufferMessage(state.payload); // Buffer the last message immediately
|
|
@@ -111,7 +131,6 @@ export class BufferService {
|
|
await this.messageModel.create(message);
|
|
await this.messageModel.create(message);
|
|
this.messageModel.countDocuments({}).then((count) => {
|
|
this.messageModel.countDocuments({}).then((count) => {
|
|
console.log(`Message${(message.message as MessageLog).appData.msgId} saved to MongoDB buffer. There is ${count} messages in datatbase under ${this.bufferIdentifier} at the moment.`);
|
|
console.log(`Message${(message.message as MessageLog).appData.msgId} saved to MongoDB buffer. There is ${count} messages in datatbase under ${this.bufferIdentifier} at the moment.`);
|
|
-
|
|
|
|
// if connection status okay
|
|
// if connection status okay
|
|
// if(this.connectionState.getValue().status == "DIRECT_PUBLISH")
|
|
// if(this.connectionState.getValue().status == "DIRECT_PUBLISH")
|
|
// {
|
|
// {
|
|
@@ -125,9 +144,17 @@ export class BufferService {
|
|
// Implement retry logic or additional error handling here
|
|
// Implement retry logic or additional error handling here
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- this.messageBuffer.push(message);
|
|
|
|
- console.log(this.messageBuffer) // Fallback to local buffer if model is not defined
|
|
|
|
- console.log(`pushing into local array buffer under ${this.bufferIdentifier}.... There is now ${this.messageBuffer.length} messages`);
|
|
|
|
|
|
+ if (this.bufferLimit > this.messageBuffered.length) {
|
|
|
|
+ this.messageBuffered.push(message);
|
|
|
|
+ console.log(this.messageBuffered) // Fallback to local buffer if model is not defined
|
|
|
|
+ console.log(`pushing into local array buffer under ${this.bufferIdentifier}.... There is now ${this.messageBuffered.length} messages`);
|
|
|
|
+ } else {
|
|
|
|
+ let reportState: ConnectionState = {
|
|
|
|
+ status: `LIMIT_EXCEEDED`,
|
|
|
|
+ reason: `${this.bufferLimit} Limit exceeded. Buffer Service will be terminated...`
|
|
|
|
+ }
|
|
|
|
+ this.connectionState.next(reportState)
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -215,12 +242,12 @@ export class BufferService {
|
|
}
|
|
}
|
|
if (!this.messageModel) {
|
|
if (!this.messageModel) {
|
|
// If MongoDB model is not defined, use the local buffer
|
|
// If MongoDB model is not defined, use the local buffer
|
|
- console.log(`Releasing buffer Message under ${this.bufferIdentifier}: currently there is ${this.messageBuffer.length} messages to be released`);
|
|
|
|
- this.messageBuffer.forEach((message) =>
|
|
|
|
|
|
+ console.log(`Releasing buffer Message under ${this.bufferIdentifier}: currently there is ${this.messageBuffered.length} messages to be released`);
|
|
|
|
+ this.messageBuffered.forEach((message) =>
|
|
this.messageStream.next(message)
|
|
this.messageStream.next(message)
|
|
);
|
|
);
|
|
- this.messageBuffer.length = 0; // Clear the local buffer after transferring
|
|
|
|
- if (this.messageBuffer.length < 1) {
|
|
|
|
|
|
+ this.messageBuffered.length = 0; // Clear the local buffer after transferring
|
|
|
|
+ if (this.messageBuffered.length < 1) {
|
|
resolve(true);
|
|
resolve(true);
|
|
} else {
|
|
} else {
|
|
reject(`Somehow the array is not emptied. This should not happen`);
|
|
reject(`Somehow the array is not emptied. This should not happen`);
|
|
@@ -231,9 +258,9 @@ export class BufferService {
|
|
|
|
|
|
private async transferLocalBufferToMongoDB(): Promise<void> {
|
|
private async transferLocalBufferToMongoDB(): Promise<void> {
|
|
return new Promise((resolve, reject) => {
|
|
return new Promise((resolve, reject) => {
|
|
- console.log(`Transferring local array buffered Message under ${this.bufferIdentifier}: currently there is ${this.messageBuffer.length}. Transferring to database...`);
|
|
|
|
|
|
+ console.log(`Transferring local array buffered Message under ${this.bufferIdentifier}: currently there is ${this.messageBuffered.length}. Transferring to database...`);
|
|
if (this.messageModel) {
|
|
if (this.messageModel) {
|
|
- let locallyBufferedMessage: Observable<Message> = from(this.messageBuffer);
|
|
|
|
|
|
+ let locallyBufferedMessage: Observable<Message> = from(this.messageBuffered);
|
|
locallyBufferedMessage.subscribe({
|
|
locallyBufferedMessage.subscribe({
|
|
next: async (message: Message) => {
|
|
next: async (message: Message) => {
|
|
try {
|
|
try {
|
|
@@ -250,7 +277,7 @@ export class BufferService {
|
|
if (this.messageModel) {
|
|
if (this.messageModel) {
|
|
this.messageModel.countDocuments({}).then((count) => {
|
|
this.messageModel.countDocuments({}).then((count) => {
|
|
console.log(`Local buffered message transfer completed. There is a total of ${count} messages in database ${this.bufferIdentifier} at the moment.`)
|
|
console.log(`Local buffered message transfer completed. There is a total of ${count} messages in database ${this.bufferIdentifier} at the moment.`)
|
|
- this.messageBuffer = [] // Clear local buffer after transferring
|
|
|
|
|
|
+ this.messageBuffered = [] // Clear local buffer after transferring
|
|
});
|
|
});
|
|
}
|
|
}
|
|
},
|
|
},
|