optimizely / optimizely/javascript-sdk

[BUG] Memory leak when migrating from v5 to v6

未关闭
#1,138 9 条评论 2 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

acknowledged bug needs-triage
主要语言
TypeScript
星标
82
派生
86
平均合并
2 天 15 小时
30 天内合并 PR
3

描述

Is there an existing issue for this?
  • I have searched the existing issues
SDK Version

6.3.1

Current Behavior

Memory increases over time and is not garbage collected

Expected Behavior

Memory is like it was before

Steps To Reproduce

We rewrote the optimizely instance creation from:

const DEFAULT_DATAFILE_OPTIONS = {
  autoUpdate: true,
  updateInterval: 5 * 60 * 1000 // 5 minutes
}

const DEFAULT_EVENTS_OPTIONS = {
  batchSize: 10,
  flushInterval: 1000
}

const DEFAULT_TIMEOUT = 500

const LOGGER_LEVEL = process.env.NODE_ENV === 'production' ? ERROR : INFO

export default class OptimizelyAdapter {
  static createOptimizelyInstance({
    options: optionParameter,
    sdkKey,
    datafile,
    optimizely = optimizelySDK,
    eventDispatcher = optimizelySDK.eventDispatcher
  }) {
    const options = {...DEFAULT_DATAFILE_OPTIONS, ...optionParameter}
    optimizely.setLogLevel(LOGGER_LEVEL)
    optimizely.setLogger(optimizely.logging.createLogger())
    if (!datafile && typeof window !== 'undefined' && window.__INITIAL_CONTEXT_VALUE__?.pde) {
      datafile = window.__INITIAL_CONTEXT_VALUE__.pde
      sdkKey = undefined
    }

    const isServer = typeof window === 'undefined'
    const optimizelyInstance = optimizely.createInstance({
      sdkKey,
      datafileOptions: options,
      datafile,
      eventDispatcher,
      ...DEFAULT_EVENTS_OPTIONS,
      defaultDecideOptions: isServer ? [optimizely.OptimizelyDecideOption.DISABLE_DECISION_EVENT] : []
    })

    return optimizelyInstance
  }
}

To:

const DEFAULT_DATAFILE_OPTIONS = {
  autoUpdate: true,
  updateInterval: 5 * 60 * 1000 // 5 minutes
}

const DEFAULT_EVENTS_OPTIONS = {
  batchSize: 10,
  flushInterval: 1000
}

const DEFAULT_TIMEOUT = 500

const LOGGER_LEVEL = process.env.NODE_ENV === 'production' ? ERROR : INFO

export default class OptimizelyAdapter {
  static createOptimizelyInstance({options: optionParameter, sdkKey, datafile}) {
    if (!datafile && typeof window !== 'undefined' && window.__INITIAL_CONTEXT_VALUE__?.pde) {
      datafile = window.__INITIAL_CONTEXT_VALUE__.pde
      sdkKey = undefined
    }

    const isServer = typeof window === 'undefined'

    const projectConfigManager = sdkKey
      ? createPollingProjectConfigManager({sdkKey, datafile, ...DEFAULT_DATAFILE_OPTIONS, ...optionParameter})
      : createStaticProjectConfigManager({datafile})

    const eventProcessor = createBatchEventProcessor({
      ...DEFAULT_EVENTS_OPTIONS,
      ...optionParameter
    })

    const odpManager = createOdpManager()

    const logger = createLogger({
      level: LOGGER_LEVEL
    })

    return createInstance({
      projectConfigManager,
      eventProcessor,
      odpManager,
      logger,
      defaultDecideOptions: isServer ? [OptimizelyDecideOption.DISABLE_DECISION_EVENT] : []
    })
  }
}

The instance is created in the server during bootstrap and we just create one. We would like to keep the current behaviour as it is (not using the disposable flag). I will try to do some memory snapshots but I was wondering is something is wrong since we only changed this part following your migration from v5 to v6 guide

SDK Type

Browser

Node Version

JS SDK

Browsers impacted

No response

Link

No response

Logs

No response

Severity

No response

Workaround/Solution

No response

Recent Change

No response

Conflicts

No response

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 issue 中展示的 v5 到 v6 实例创建变更开始,并复现创建一个实例的 server-bootstrap 场景。比较一段时间内的内存快照,重点关注项目配置管理器、事件处理器、ODP 管理器、logger 和 createInstance 路径。在不启用 disposable flag 的情况下,确定保留内存的来源并确认内存行为稳定,即视为完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
javascript
领域
backend, performance
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
需要澄清
新手友好度
28/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。