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
}