Skip to content

Restart command should use the native restart API, not chain Stop → Start #2898

Description

Summary

src/commands/restartWebApp.ts implements Restart by chaining two separate commands:

export async function restartWebApp(context: IActionContext, node?: SiteTreeItem): Promise<void> {
    node ??= await pickWebApp(context);
    await commands.executeCommand('appService.Stop', node);
    await commands.executeCommand('appService.Start', node);
}

This is not equivalent to POST /sites/{name}/restart (the ARM/Kudu native restart) and has two concrete failure modes:

Failure mode 1: leaves the app stopped on Start failure

If appService.Stop succeeds but appService.Start fails (transient ARM 5xx, throttling, quota check, network glitch), the site is left in the Stopped state. The user asked to restart, not to stop. They now have an unexpected outage and must manually re-run Start.

The native client.restart() is atomic on the ARM side — either the restart command is accepted or it isn't; there is no intermediate stopped state observable from outside.

Failure mode 2: unnecessary downtime window

Chaining Stop → Start introduces a longer downtime window than a native restart. client.restart() recycles the worker processes without fully deallocating and reallocating the site, so cold-start cost is avoided.

Proposed fix

Replace the body with a direct native-restart call, matching the pattern used elsewhere in the extension:

export async function restartWebApp(context: IActionContext, node?: SiteTreeItem): Promise<void> {
    node ??= await pickWebApp(context);
    await node.initSite(context);
    const client = await node.site.createClient(context);
    const restartingApp = localize('restartingApp', 'Restarting "{0}"...', node.site.fullName);
    const restartedApp = localize('restartedApp', '"{0}" has been restarted.', node.site.fullName);
    await node.runWithTemporaryDescription(context, localize('restarting', "Restarting..."), async () => {
        ext.outputChannel.appendLog(restartingApp);
        await client.restart();
        ext.outputChannel.appendLog(restartedApp);
    });
}

@azure/arm-appservice WebSiteManagementClient.webApps.restart(resourceGroupName, name) (and the slot variant) is already available through the same client wrapper stopWebApp.ts uses.

Happy to open a PR.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions