Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restart the event listener every 5 minutes #3693

Merged
merged 4 commits into from
Nov 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,8 @@ export abstract class DockerClientBase extends ConfigurableClient implements ICo
): CommandLineArgs {
return composeArgs(
withArg('events'),
withNamedArg('--since', options.since),
withNamedArg('--until', options.until),
withNamedArg('--since', options.since?.toString(), { shouldQuote: !(typeof options.since === 'number') }), // If it's numeric it should not be quoted
withNamedArg('--until', options.until?.toString(), { shouldQuote: !(typeof options.until === 'number') }), // If it's numeric it should not be quoted
withDockerLabelFilterArgs(options.labels),
withNamedArg('--filter', options.types?.map((type) => `type=${type}`)),
withNamedArg('--filter', options.events?.map((event) => `event=${event}`)),
Expand Down
4 changes: 2 additions & 2 deletions src/runtimes/docker/contracts/ContainerClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,11 @@ export type EventStreamCommandOptions = CommonCommandOptions & {
/**
* Return events since a given timestamp
*/
since?: string;
since?: string | number;
/**
* Only stream events until a given timestamp
*/
until?: string;
until?: string | number;
/**
* Only listen for events affecting these object types
*/
Expand Down
20 changes: 17 additions & 3 deletions src/tree/RefreshManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { AllTreePrefixes, TreePrefix } from './TreePrefix';

const pollingIntervalMs = 60 * 1000; // One minute
const eventListenerTries = 3; // The event listener will try at most 3 times to connect for events
const eventListenerLifetimeSeconds = 60 * 5; // Five minutes
const debounceDelayMs = 500; // Refreshes rapidly initiated for the same tree view will be debounced to occur 500ms after the last initiation

type RefreshTarget = AzExtTreeItem | TreePrefix;
Expand Down Expand Up @@ -108,12 +109,18 @@ export class RefreshManager extends vscode.Disposable {
const eventActionsToWatch: EventAction[] = Array.from(new Set<EventAction>([...ContainerEventActions, ...ImageEventActions, ...NetworkEventActions, ...VolumeEventActions]));

// Try at most `eventListenerTries` times to (re)connect to the event stream
for (let i = 0; i < eventListenerTries; i++) {
let errorCount = 0;
let eventsSinceTimestamp = Math.round(Date.now() / 1000);
while (errorCount < eventListenerTries) {
const eventsUntilTimestamp = eventsSinceTimestamp + eventListenerLifetimeSeconds;

try {
const eventGenerator = ext.streamWithDefaultShell(client =>
client.getEventStream({
types: eventTypesToWatch,
events: eventActionsToWatch,
since: eventsSinceTimestamp,
until: eventsUntilTimestamp,
}),
{
cancellationToken: this.cts.token,
Expand Down Expand Up @@ -145,7 +152,7 @@ export class RefreshManager extends vscode.Disposable {
if (isCancellationError(err) || error.isUserCancelledError) {
// Cancelled, so don't try again and don't rethrow--this is a normal termination pathway
return;
} else if (i < eventListenerTries - 1) {
} else if (++errorCount < eventListenerTries) {
// Still in the retry loop
continue;
} else {
Expand All @@ -156,10 +163,17 @@ export class RefreshManager extends vscode.Disposable {

throw error;
}
} finally {
// Move the next start timestamp to the current end timestamp
eventsSinceTimestamp = eventsUntilTimestamp;
}

// If the event generator terminates on its expected lifecycle it will exit without an error
// Continue the loop as normal, starting the next event stream at the previous stop time
bwateratmsft marked this conversation as resolved.
Show resolved Hide resolved
// We intentionally do not reset the `errorCount`, so that at most 3 failures occur before
// giving up, regardless of whether or not they are consecutive.
}
});

}

private setupRefreshOnConfigurationChange(): void {
Expand Down