From 752c15e7984a6eae5ccf32eb572fe0fe767324d3 Mon Sep 17 00:00:00 2001
From: JJ Kasper <jj@jjsweb.site>
Date: Thu, 18 Jan 2024 08:49:35 -0800
Subject: [PATCH] Add metrics names for unstable_cache (#60802)

This ensures we add params for `unstable_cache` so it can be identified
the same was as fetches instead of being unlabeled.

Closes NEXT-2143
---
 .../web/spec-extension/unstable-cache.ts      | 26 ++++++++++++++++---
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/packages/next/src/server/web/spec-extension/unstable-cache.ts b/packages/next/src/server/web/spec-extension/unstable-cache.ts
index b2e61127da71f..8533fa3fa7909 100644
--- a/packages/next/src/server/web/spec-extension/unstable-cache.ts
+++ b/packages/next/src/server/web/spec-extension/unstable-cache.ts
@@ -14,12 +14,16 @@ import {
 
 type Callback = (...args: any[]) => Promise<any>
 
+let noStoreFetchIdx = 0
+
 async function cacheNewResult<T>(
   result: T,
   incrementalCache: IncrementalCache,
   cacheKey: string,
   tags: string[],
-  revalidate: number | false | undefined
+  revalidate: number | false | undefined,
+  fetchIdx: number,
+  fetchUrl: string
 ): Promise<unknown> {
   await incrementalCache.set(
     cacheKey,
@@ -38,6 +42,8 @@ async function cacheNewResult<T>(
       revalidate,
       fetchCache: true,
       tags,
+      fetchIdx,
+      fetchUrl,
     }
   )
   return
@@ -104,8 +110,12 @@ export function unstable_cache<T extends Callback>(
     // the keyspace smaller than the execution space
     const invocationKey = `${fixedKey}-${JSON.stringify(args)}`
     const cacheKey = await incrementalCache.fetchCacheKey(invocationKey)
+    const fetchUrl = `unstable_cache ${cb.name ? ` ${cb.name}` : cacheKey}`
+    const fetchIdx = (store ? store.nextFetchId : noStoreFetchIdx) ?? 1
 
     if (store) {
+      store.nextFetchId = fetchIdx + 1
+
       // We are in an App Router context. We try to return the cached entry if it exists and is valid
       // If the entry is fresh we return it. If the entry is stale we return it but revalidate the entry in
       // the background. If the entry is missing or invalid we generate a new entry and return it.
@@ -156,6 +166,7 @@ export function unstable_cache<T extends Callback>(
           revalidate: options.revalidate,
           tags,
           softTags: implicitTags,
+          fetchIdx,
         })
 
         if (cacheEntry && cacheEntry.value) {
@@ -198,7 +209,9 @@ export function unstable_cache<T extends Callback>(
                       incrementalCache,
                       cacheKey,
                       tags,
-                      options.revalidate
+                      options.revalidate,
+                      fetchIdx,
+                      fetchUrl
                     )
                   })
                   // @TODO This error handling seems wrong. We swallow the error?
@@ -232,10 +245,13 @@ export function unstable_cache<T extends Callback>(
         incrementalCache,
         cacheKey,
         tags,
-        options.revalidate
+        options.revalidate,
+        fetchIdx,
+        fetchUrl
       )
       return result
     } else {
+      noStoreFetchIdx += 1
       // We are in Pages Router or were called outside of a render. We don't have a store
       // so we just call the callback directly when it needs to run.
       // If the entry is fresh we return it. If the entry is stale we return it but revalidate the entry in
@@ -295,7 +311,9 @@ export function unstable_cache<T extends Callback>(
         incrementalCache,
         cacheKey,
         tags,
-        options.revalidate
+        options.revalidate,
+        fetchIdx,
+        fetchUrl
       )
       return result
     }