多实例与配置设计
3.0 中计划要进行以下的改动,这里一起讨论:
- 支持多实例
- 新的配置 API
- app router v2
多实例指的是在一个线程中实例化两个 App 的实例。这就要求所有的实例都需要知道自己是属于哪个 App 的,要做到这点,改动成本最小的方案是利用闭包。
在最早的版本中,SDK 的代码是这样的:
// av.js
const AV = {};
require('./query')(AV);
// query.js
module.exports = AV => {
AV.Query = function() {};
};
为了实践模块化,后来将部分模块改成了「正常」的样子:
// av.js
const AV = {};
// request.js
const AV = require('./av');
exports.request = () => {
// AV.xxx
};
// query.js
const request = require('./request').request;
现在,要将 request 等模块也改回从作用域中取 AV 的方式。这个改动可能会影响 apm 的 spy 代码。在 API 上会新增 AV.fork() 返回一个新的未初始化 AV。
支持多实例之后暴露出的另一个问题是配置,之前除了 AV.init 之外,还存在 AV.setProduction,以及直接修改 AV._config.[APIServerURL|disableCurrentUser] 的配置方式,后续还会有允许用户配置 localStorage 接口实现的需求。因此在这次改动中,将上述这些配置全都放在 AV.init 的字典参数中,为了避免与 init 方法先后调用可能造成的问题,这些配置绝大部分都不再提供单独的 setter,仅保留 AV.setProduction 与 AV.disableCurrentUser 两个方法。在 AV.fork() 返回的新 AV 中,所有的配置都会被重置为初始值。
引入 app router v2 之后会 APIServerURL 配置不再是一个 url 了,所以除了内部的 serviceHosts,还要在维护一个用户配置的 userServiceHosts,读的时候先从 userServiceHosts 中读。这里还会有个问题是在某些异常的情况下(307)需要刷新 app router,如果用户配置了错误的 host,可能会导致不断刷新 app router。
@leancloud/leanengine
如果通过闭包来实现的话,一个 AV.Object 实例,能否有方法判断出自己属于哪个 App?
可以有一个 ._getAV 的方法,需要靠这个来检查交叉引用。