public async fetchNextLogEvents()

in packages/core/src/awsService/cloudWatchLogs/registry/logDataRegistry.ts [68:161]


    public async fetchNextLogEvents(
        uri: vscode.Uri,
        headOrTail: 'head' | 'tail' = 'tail'
    ): Promise<CloudWatchLogsEvent[]> {
        if (!this.isRegistered(uri)) {
            this.registerInitialLog(uri)
        }

        const logData = this.getRegisteredLog(uri)
        const request: CloudWatchLogsResponse = {
            events: [],
            nextForwardToken: logData.next?.token,
            nextBackwardToken: logData.previous?.token,
        }

        const isHead = headOrTail === 'head'

        // We are at the earliest data and trying to go back in time, there is nothing to see.
        // If we don't return now, redundant data will be retrieved.
        if (isHead && logData.previous?.token === undefined) {
            // show something so the user doesn't think nothing happened.
            await Messages.putMessage(
                msgKey(logData.logGroupInfo),
                `Loading from: '${logData.logGroupInfo.groupName}'`,
                undefined,
                500
            )
            return []
        }

        const stream = pageableToCollection(
            (r: typeof request) =>
                logData.retrieveLogsFunction(
                    logData.logGroupInfo,
                    logData.parameters,
                    isHead ? r.nextBackwardToken : r.nextForwardToken
                ),
            request,
            isHead ? 'nextBackwardToken' : 'nextForwardToken'
        )

        async function firstOrLast<T>(
            iterable: AsyncIterable<T>,
            predicate: (item: T) => boolean
        ): Promise<T | undefined> {
            let last: T | undefined
            for await (const item of iterable) {
                if (predicate((last = item))) {
                    return item
                }
            }
            return last
        }

        const msgTimeout = await Messages.putMessage(
            msgKey(logData.logGroupInfo),
            `Loading from: '${logData.logGroupInfo.groupName}'`
        )
        const responseData = await firstOrLast(stream, (resp) => resp.events.length > 0).finally(() => {
            msgTimeout.dispose()
        })

        if (!responseData) {
            return []
        }

        const newData =
            headOrTail === 'head'
                ? (responseData.events ?? []).concat(logData.events)
                : logData.events.concat(responseData.events ?? [])

        const tokens: Pick<CloudWatchLogsData, 'next' | 'previous'> = {}
        // update if no token exists or if the token is updated in the correct direction.
        if (!logData.previous || headOrTail === 'head') {
            const token = responseData.nextBackwardToken
            if (token) {
                tokens.previous = { token }
            }
        }
        if (!logData.next || headOrTail === 'tail') {
            const token = responseData.nextForwardToken ?? request.nextForwardToken
            if (token) {
                tokens.next = { token }
            }
        }
        this.setLogData(uri, {
            ...logData,
            ...tokens,
            events: newData,
        })

        this._onDidChange.fire(uri)
        return newData
    }