Repository: artusjs/core
Pull request #264 (2023-08-30 11:29:41)

fix: reverse emit function list when beforeClose hook
beforeClose 钩子通常用于进行业务逻辑的收尾处理，此时仍可能使用插件提供的 Client；

正向触发 hook 可能造成插件中的链接比应用更早被回收，不符合预期；

所以简单地针对这个钩子，在 emitHook 阶段反转 fnList

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/artusjs/core/pull/264?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=artusjs) Report
Patch coverage: **`100.00%`** and project coverage change: **`+0.01%`** :tada:
> Comparison is base [(`d9528e0`)](https://app.codecov.io/gh/artusjs/core/commit/d9528e0e40378535af3d88670faa98e6bb8f90e5?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=artusjs) 91.63% compared to head [(`3b7ad46`)](https://app.codecov.io/gh/artusjs/core/pull/264?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=artusjs) 91.65%.

:exclamation: Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please [install the Github App Integration](https://github.com/apps/codecov) for your organization. [Read more](https://about.codecov.io/blog/codecov-is-updating-its-github-integration/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=artusjs).

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master     #264      +/-   ##
==========================================
+ Coverage   91.63%   91.65%   +0.01%     
==========================================
  Files          49       49              
  Lines        1184     1186       +2     
  Branches      212      214       +2     
==========================================
+ Hits         1085     1087       +2     
  Misses         99       99              
```


| [Files Changed](https://app.codecov.io/gh/artusjs/core/pull/264?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=artusjs) | Coverage Δ | |
|---|---|---|
| [src/application.ts](https://app.codecov.io/gh/artusjs/core/pull/264?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=artusjs#diff-c3JjL2FwcGxpY2F0aW9uLnRz) | `88.40% <100.00%> (ø)` | |
| [src/lifecycle/index.ts](https://app.codecov.io/gh/artusjs/core/pull/264?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=artusjs#diff-c3JjL2xpZmVjeWNsZS9pbmRleC50cw==) | `88.00% <100.00%> (+0.50%)` | :arrow_up: |


</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/artusjs/core/pull/264?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=artusjs).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=artusjs).


Patch:
diff --git a/src/application.ts b/src/application.ts
index 31b86f3..c8246d4 100644
--- a/src/application.ts
+++ b/src/application.ts
@@ -80,7 +80,8 @@ export class ArtusApplication implements Application {
 
   async close(exit = false) {
     try {
-      await this.lifecycleManager.emitHook('beforeClose');
+      // reverse emitHook to avoid plugin closed before app hook
+      await this.lifecycleManager.emitHook('beforeClose', null, true);
     } catch (e) {
       throw new Error(e);
     }
diff --git a/src/lifecycle/index.ts b/src/lifecycle/index.ts
index f8b69bf..d30b37e 100644
--- a/src/lifecycle/index.ts
+++ b/src/lifecycle/index.ts
@@ -70,7 +70,7 @@ export class LifecycleManager {
     }
   }
 
-  async emitHook<T = unknown>(hookName: string, payload?: T) {
+  async emitHook<T = unknown>(hookName: string, payload?: T, reverse = false) {
     if (!this.enable) {
       return;
     }
@@ -83,6 +83,9 @@ export class LifecycleManager {
     }
     // lifecycle hook should only trigger one time
     this.hookFnMap.delete(hookName);
+    if (reverse) {
+      fnList.reverse();
+    }
     for (const hookFn of fnList) {
       await hookFn({
         app: this.app,


Test patch:
diff --git a/test/lifecycle.test.ts b/test/lifecycle.test.ts
index b1c302a..ed255af 100644
--- a/test/lifecycle.test.ts
+++ b/test/lifecycle.test.ts
@@ -46,9 +46,9 @@ describe('test/lifecycle.test.ts', () => {
       'pluginA_didReady',
       'pluginB_didReady',
       'app_didReady',
-      'pluginA_beforeClose',
-      'pluginB_beforeClose',
       'app_beforeClose',
+      'pluginB_beforeClose',
+      'pluginA_beforeClose',
     ]);
   });
 
@@ -84,9 +84,9 @@ describe('test/lifecycle.test.ts', () => {
       'pluginA_didReady',
       'pluginB_didReady',
       'app_didReady',
-      'pluginA_beforeClose',
-      'pluginB_beforeClose',
       'app_beforeClose',
+      'pluginB_beforeClose',
+      'pluginA_beforeClose',
     ]);
   });