|
1 | 1 | import type { WriteStream } from "fs"; |
2 | | -import { createWriteStream, mkdtemp, pathExists, remove } from "fs-extra"; |
| 2 | +import { |
| 3 | + createWriteStream, |
| 4 | + mkdtemp, |
| 5 | + pathExists, |
| 6 | + remove, |
| 7 | + writeJson, |
| 8 | +} from "fs-extra"; |
3 | 9 | import { tmpdir } from "os"; |
4 | 10 | import { delimiter, dirname, join } from "path"; |
5 | 11 | import { Range, satisfies } from "semver"; |
@@ -28,6 +34,7 @@ import { reportUnzipProgress } from "../common/vscode/unzip-progress"; |
28 | 34 | import type { Release } from "./distribution/release"; |
29 | 35 | import { ReleasesApiConsumer } from "./distribution/releases-api-consumer"; |
30 | 36 | import { createTimeoutSignal } from "../common/fetch-stream"; |
| 37 | +import { withDistributionUpdateLock } from "./lock"; |
31 | 38 |
|
32 | 39 | /** |
33 | 40 | * distribution.ts |
@@ -350,9 +357,24 @@ class ExtensionSpecificDistributionManager { |
350 | 357 | release: Release, |
351 | 358 | progressCallback?: ProgressCallback, |
352 | 359 | ): Promise<void> { |
353 | | - await this.downloadDistribution(release, progressCallback); |
354 | | - // Store the installed release within the global extension state. |
355 | | - await this.storeInstalledRelease(release); |
| 360 | + const distributionStatePath = join( |
| 361 | + this.extensionContext.globalStorageUri.fsPath, |
| 362 | + ExtensionSpecificDistributionManager._distributionStateFilename, |
| 363 | + ); |
| 364 | + if (!(await pathExists(distributionStatePath))) { |
| 365 | + // This may result in a race condition, but when this happens both processes should write the same file. |
| 366 | + await writeJson(distributionStatePath, {}); |
| 367 | + } |
| 368 | + |
| 369 | + await withDistributionUpdateLock( |
| 370 | + // .lock will be appended to this filename |
| 371 | + distributionStatePath, |
| 372 | + async () => { |
| 373 | + await this.downloadDistribution(release, progressCallback); |
| 374 | + // Store the installed release within the global extension state. |
| 375 | + await this.storeInstalledRelease(release); |
| 376 | + }, |
| 377 | + ); |
356 | 378 | } |
357 | 379 |
|
358 | 380 | private async downloadDistribution( |
@@ -615,6 +637,7 @@ class ExtensionSpecificDistributionManager { |
615 | 637 | "distributionFolderIndex"; |
616 | 638 | private static readonly _installedReleaseStateKey = "distributionRelease"; |
617 | 639 | private static readonly _codeQlExtractedFolderName = "codeql"; |
| 640 | + private static readonly _distributionStateFilename = "distribution.json"; |
618 | 641 | } |
619 | 642 |
|
620 | 643 | /* |
|
0 commit comments