Skip to content

Each request creates an Alova instance, causing a memory leak on the server #647

@chen6516

Description

@chen6516

Is this a Bug?

  • I have confirmed that I want to report a Bug

Has this issue been reported before?

  • I have confirmed that this Issue has not been reported before

Alova Version

3.x

Framework

Nodejs

Problem Description

packages/alova/src/alova.ts

  constructor(options: AlovaOptions<AG>) {
    const instance = this;
    instance.id = (options.id || (idCount += 1)).toString();
    // If storage is not specified, local storage is used by default.
    instance.l1Cache = options.l1Cache || memoryAdapter();
    instance.l2Cache = options.l2Cache || localStorageAdapter();

    // Merge default options
    instance.options = {
      ...(defaultAlovaOptions as Partial<AlovaOptions<AG>>),
      ...options
    };
    instance.snapshots = newInstance(
      MethodSnapshotContainer<AG>,
      options.snapshots ?? defaultAlovaOptions.snapshots ?? 0
    );
  }
export const createAlova = <
  RequestConfig,
  Response,
  ResponseHeader,
  L1Cache extends AlovaGlobalCacheAdapter = AlovaDefaultCacheAdapter,
  L2Cache extends AlovaGlobalCacheAdapter = AlovaDefaultCacheAdapter
>(
  options: AlovaOptions<AlovaGenerics<any, any, RequestConfig, Response, ResponseHeader, L1Cache, L2Cache>>
) => {
  const alovaInstance = newInstance(
    Alova<AlovaGenerics<any, any, RequestConfig, Response, ResponseHeader, L1Cache, L2Cache>>,
    options
  );
  const newStatesHook = alovaInstance.options.statesHook;
  if (boundStatesHook) {
    myAssert(boundStatesHook === newStatesHook, 'expected to use the same `statesHook`');
  }
  boundStatesHook = newStatesHook;


  const { l1Cache, l2Cache } = alovaInstance;
  !usingL1CacheAdapters.includes(l1Cache) && pushItem(usingL1CacheAdapters, l1Cache);
  !usingL2CacheAdapters.includes(l2Cache) && pushItem(usingL2CacheAdapters, l2Cache);
  return alovaInstance;
};

When rendering on the server side, l1Cache/l2Cache user configuration is null or undefined, and each request (each request will call createServerAlova to create an alova instance)
usingL1CacheAdapters/usingL2CacheAdapters will be pushed to the default l1Cache/l2Cache, resulting in a memory leak.

In a stateless multi-user node.js system, each request will create a new alova instance to request (each user's authentication information header is different, although the request is to the same address, the returned data is the user's own private data, and the cache is handled by the API, so the front-end service does not use the cache)
So I encountered this problem

Expected Behavior

If cacheFor is null, no cache should be used, including l1Cache, l2Cache

Reproduction Link

No response

Reproduction Steps

In the node.js server-side rendering program, each request will call the createAlova method to create a request instance. The configuration snippet is as follows:

createAlova({
    baseURL: `${apiUrl}${reqUrl}`,
    timeout: 30000,

    statesHook: VueHook,
    cacheFor: null,
    l1Cache: void 0,
    l2Cache: void 0,

    requestAdapter: axiosRequestAdapter(),
    cacheLogger: import.meta.env.DEV,
}

System Information

Additional Information

We used the following method to temporarily solve:

const emptyCache = {
  set: () => void 0,
  get: () => void 0,
  remove: () => void 0,
  clear: () => void 0,
  emitter: createEventManager(),
} as AlovaDefaultCacheAdapter;


createAlova({
    baseURL: `${apiUrl}${reqUrl}`,
    timeout: 30000,

    statesHook: VueHook,
    cacheFor: null,
    l1Cache: emptyCache,
    l2Cache: emptyCache,

    requestAdapter: axiosRequestAdapter(),
    cacheLogger: import.meta.env.DEV,
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions