fix: avoid concurrent configuration change callback execution
authorJérôme Benoit <jerome.benoit@sap.com>
Tue, 7 Nov 2023 22:20:34 +0000 (23:20 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Tue, 7 Nov 2023 22:20:34 +0000 (23:20 +0100)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
src/utils/Configuration.ts

index 48b4897f9e4cd44cb43b95c71702bc6de5386598..4b10778bd13b961b8fa234a6233581f34e82d9a0 100644 (file)
@@ -56,6 +56,7 @@ export class Configuration {
     'config.json',
   );
 
+  private static configurationFileReloading = false;
   private static configurationData?: ConfigurationData;
   private static configurationFileWatcher?: FSWatcher;
   private static configurationSectionCache = new Map<
@@ -546,8 +547,14 @@ export class Configuration {
   private static getConfigurationFileWatcher(): FSWatcher | undefined {
     try {
       return watch(Configuration.configurationFile, (event, filename): void => {
-        if (filename!.trim()!.length > 0 && event === 'change') {
-          console.warn(
+        if (
+          !Configuration.configurationFileReloading &&
+          filename!.trim()!.length > 0 &&
+          event === 'change'
+        ) {
+          Configuration.configurationFileReloading = true;
+          const consoleWarnOnce = once(console.warn, this);
+          consoleWarnOnce(
             `${chalk.green(configurationLogPrefix())} ${chalk.yellow(
               `${FileType.Configuration} ${this.configurationFile} file have changed, reload`,
             )}`,
@@ -555,9 +562,13 @@ export class Configuration {
           delete Configuration.configurationData;
           Configuration.configurationSectionCache.clear();
           if (!isUndefined(Configuration.configurationChangeCallback)) {
-            Configuration.configurationChangeCallback().catch((error) => {
-              throw typeof error === 'string' ? new Error(error) : error;
-            });
+            Configuration.configurationChangeCallback()
+              .catch((error) => {
+                throw typeof error === 'string' ? new Error(error) : error;
+              })
+              .finally(() => {
+                Configuration.configurationFileReloading = false;
+              });
           }
         }
       });