[SSE] Event stream TTL refresh (#17337)
This PR update the redis subscription iterator wrapper with an heartbeat system. Heartbeat interval are based on event stream TTL. Those refresh the event stream TTL and active streams in redis. I also cleaned a few functions that were not used anymore. --------- Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
This commit is contained in:
@@ -15,7 +15,6 @@ import {
|
||||
EventStreamExceptionCode,
|
||||
} from 'src/engine/subscriptions/event-stream.exception';
|
||||
import { type EventStreamData } from 'src/engine/subscriptions/types/event-stream-data.type';
|
||||
import { type ObjectRecordSubscriptionEvent } from 'src/engine/subscriptions/types/object-record-subscription-event.type';
|
||||
|
||||
@Injectable()
|
||||
export class EventStreamService {
|
||||
@@ -131,15 +130,6 @@ export class EventStreamService {
|
||||
return result;
|
||||
}
|
||||
|
||||
async getStreamData(
|
||||
workspaceId: string,
|
||||
eventStreamChannelId: string,
|
||||
): Promise<EventStreamData | undefined> {
|
||||
const key = this.getEventStreamKey(workspaceId, eventStreamChannelId);
|
||||
|
||||
return this.cacheStorageService.get<EventStreamData>(key);
|
||||
}
|
||||
|
||||
async isAuthorized({
|
||||
workspaceId,
|
||||
eventStreamChannelId,
|
||||
@@ -214,40 +204,25 @@ export class EventStreamService {
|
||||
}
|
||||
}
|
||||
|
||||
async getQueries(
|
||||
workspaceId: string,
|
||||
eventStreamId: string,
|
||||
): Promise<Map<string, RecordGqlOperationSignature>> {
|
||||
const streamData = await this.getStreamData(workspaceId, eventStreamId);
|
||||
async refreshEventStreamTTL({
|
||||
workspaceId,
|
||||
eventStreamChannelId,
|
||||
}: {
|
||||
workspaceId: string;
|
||||
eventStreamChannelId: string;
|
||||
}): Promise<boolean> {
|
||||
const eventStreamKey = this.getEventStreamKey(
|
||||
workspaceId,
|
||||
eventStreamChannelId,
|
||||
);
|
||||
const activeStreamsKey = this.getActiveStreamsKey(workspaceId);
|
||||
|
||||
if (!isDefined(streamData)) {
|
||||
return new Map();
|
||||
}
|
||||
const [eventStreamRefreshed, activeStreamsRefreshed] = await Promise.all([
|
||||
this.cacheStorageService.expire(eventStreamKey, EVENT_STREAM_TTL_MS),
|
||||
this.cacheStorageService.expire(activeStreamsKey, EVENT_STREAM_TTL_MS),
|
||||
]);
|
||||
|
||||
return new Map(Object.entries(streamData.queries));
|
||||
}
|
||||
|
||||
matchQueriesWithEvent(
|
||||
queries: Record<string, RecordGqlOperationSignature>,
|
||||
event: ObjectRecordSubscriptionEvent,
|
||||
): string[] {
|
||||
const matchedQueryIds: string[] = [];
|
||||
|
||||
for (const [queryId, operationSignature] of Object.entries(queries)) {
|
||||
if (this.isQueryMatchingEvent(operationSignature, event)) {
|
||||
matchedQueryIds.push(queryId);
|
||||
}
|
||||
}
|
||||
|
||||
return matchedQueryIds;
|
||||
}
|
||||
|
||||
private isQueryMatchingEvent(
|
||||
operationSignature: RecordGqlOperationSignature,
|
||||
event: ObjectRecordSubscriptionEvent,
|
||||
): boolean {
|
||||
// to be improved
|
||||
return operationSignature.objectNameSingular === event.objectNameSingular;
|
||||
return eventStreamRefreshed && activeStreamsRefreshed;
|
||||
}
|
||||
|
||||
private getEventStreamKey(
|
||||
@@ -260,4 +235,13 @@ export class EventStreamService {
|
||||
private getActiveStreamsKey(workspaceId: string): string {
|
||||
return `workspace:${workspaceId}:activeStreams`;
|
||||
}
|
||||
|
||||
private async getStreamData(
|
||||
workspaceId: string,
|
||||
eventStreamChannelId: string,
|
||||
): Promise<EventStreamData | undefined> {
|
||||
const key = this.getEventStreamKey(workspaceId, eventStreamChannelId);
|
||||
|
||||
return this.cacheStorageService.get<EventStreamData>(key);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user