From 608d0f6a4001a761c50b56743ee94c83cce72ba1 Mon Sep 17 00:00:00 2001
From: Sergei Zharinov <zharinov@users.noreply.github.com>
Date: Sun, 1 May 2022 07:00:55 +0300
Subject: [PATCH] feat: Create utility for function memoization (#15373)

* feat: Create utility for function memoization

* Simplify
---
 lib/util/memoize.spec.ts                  | 17 +++++++++++++++++
 lib/util/memoize.ts                       | 17 +++++++++++++++++
 lib/workers/repository/update/pr/index.ts | 13 ++++---------
 3 files changed, 38 insertions(+), 9 deletions(-)
 create mode 100644 lib/util/memoize.spec.ts
 create mode 100644 lib/util/memoize.ts

diff --git a/lib/util/memoize.spec.ts b/lib/util/memoize.spec.ts
new file mode 100644
index 0000000000..743d33295a
--- /dev/null
+++ b/lib/util/memoize.spec.ts
@@ -0,0 +1,17 @@
+import { memoize } from './memoize';
+
+describe('util/memoize', () => {
+  let calledTimes = 0;
+
+  it('works', () => {
+    const fn = (): number => {
+      calledTimes += 1;
+      return calledTimes;
+    };
+    const memFn = memoize(fn);
+
+    expect(memFn()).toBe(1);
+    expect(memFn()).toBe(1);
+    expect(calledTimes).toBe(1);
+  });
+});
diff --git a/lib/util/memoize.ts b/lib/util/memoize.ts
new file mode 100644
index 0000000000..ae3be629d3
--- /dev/null
+++ b/lib/util/memoize.ts
@@ -0,0 +1,17 @@
+interface Result<T = unknown> {
+  res: T;
+}
+
+export function memoize<T = unknown>(callback: () => T): () => T {
+  let memo: null | Result<T> = null;
+
+  return (): T => {
+    if (memo) {
+      return memo.res;
+    }
+
+    const res = callback();
+    memo = { res };
+    return res;
+  };
+}
diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts
index 55ef9ded48..2b8b01b932 100644
--- a/lib/workers/repository/update/pr/index.ts
+++ b/lib/workers/repository/update/pr/index.ts
@@ -12,6 +12,7 @@ import { BranchStatus } from '../../../../types';
 import { ExternalHostError } from '../../../../types/errors/external-host-error';
 import { stripEmojis } from '../../../../util/emoji';
 import { deleteBranch, getBranchLastCommitTime } from '../../../../util/git';
+import { memoize } from '../../../../util/memoize';
 import { regEx } from '../../../../util/regex';
 import { Limit, incLimitedValue, isLimitReached } from '../../../global/limits';
 import type {
@@ -63,15 +64,9 @@ export type EnsurePrResult = ResultWithPr | ResultWithoutPr;
 export async function ensurePr(
   prConfig: BranchConfig
 ): Promise<EnsurePrResult> {
-  let branchStatus: BranchStatus;
-  async function getBranchStatus(): Promise<BranchStatus> {
-    if (branchStatus) {
-      return branchStatus;
-    }
-    branchStatus = await resolveBranchStatus(branchName, ignoreTests);
-    logger.debug(`Branch status is: ${branchStatus}`);
-    return branchStatus;
-  }
+  const getBranchStatus = memoize(() =>
+    resolveBranchStatus(branchName, ignoreTests)
+  );
 
   const config: BranchConfig = { ...prConfig };
 
-- 
GitLab