跳到主要内容
版本:v3

进程共享适配器

进程共享存储适配器可以在多进程环境中共享 Alova 的缓存。

其中默认实现了两个适配器,可以在 Node.js 和 Electron 环境中使用。

Tips

仅支持 Alova 3.0 以上版本

安装

# npm
npm install alova @alova/psc --save
# yarn
yarn add alova @alova/psc
# npm
pnpm install alova @alova/psc

在 Node.js 中使用

在 Node.js 环境中,使用 createNodePSCSynchronizercreatePSCAdapter 来实现各子进程之间的缓存同步。

  1. 在主进程中设置同步器:
const cluster = require('cluster');
const { createNodePSCSynchronizer } = require('@alova/psc');

if (cluster.isMaster) {
// 确保在创建子进程之前调用
await createNodePSCSynchronizer();
} else {
// fork worker processes
}
  1. 在子进程中使用适配器:

通常情况下,像这样使用即可:

const { createPSCAdapter, NodeSyncAdapter } = require('@alova/psc');

createAlova({
// ...
l1Cache: createPSCAdapter(NodeSyncAdapter())
});

共享多个缓存

当然,同时共享 l1Cachel2Cache 也完全没有问题!使用 scope 选项,并创建不同的共享储存适配器即可。

const process = require('node:process');

const createScopedPSCAdapter = (scope: string) =>
createPSCAdapter(
NodeSyncAdapter(),
// 这个参数用于指定储存适配器,我们稍后会介绍
undefined,
{ scope }
);

createAlova({
// ...
l1Cache: createScopedPSCAdapter('l1'),
l2Cache: createScopedPSCAdapter('l2')
});

在 Electron 中使用

在 Electron 环境中,使用 createElectronPSCSynchronizercreatePSCAdapter 来实现各渲染进程之间的缓存同步。

  1. 在主进程中设置同步器:
// main.js
import { createElectronPSCSynchronizer } from '@alova/psc';
import { ipcMain } from 'electron';

// 初始化同步器
createElectronPSCSynchronizer(ipcMain);

// ...other codes
  1. 在渲染进程中使用适配器并暴露到全局对象:
// payload.js
import { createPSCAdapter, ElectronSyncAdapter } from '@alova/psc';
import { ipcRenderer, contextBridge } from 'electron';

const pscAdapter = createPSCAdapter(ElectronSyncAdapter(ipcRenderer));

contextBridge.exposeInMainWorld('pscAdapter', pscAdapter);
  1. 在创建 alova 实例时使用:
import { createAlova } from 'alova';

const alova = createAlova({
// ...
l1Cache: window.pscAdapter
});

如果使用 typescript,不要忘记补充全局类型:

// env.d.ts
declare global {
interface Window {
// ...
pscAdapter: import('@alova/psc').SyncAdapter;
}
}
note

当使用多个 alova 实例时,无需为其创建多个 PSCAdapter 对象。Alova 实例之间通过不同的 id 来标识自身,因此可安全地复用同一通道。

自定义储存适配器

通过传入 createPSCAdapter 的第二个参数,可指定使用的储存适配器。

const pscAdapter = createPSCAdapter(
ElectronSyncAdapter(
ipcRenderer,
// 用法与 createAlova 时传入到 l1Cache 一致。如果传入 undefined,那么将使用默认实现
MyStorageAdapter()
)
);

createAlova({
// ...
l1Cache: pscAdapter
});

你还可以使用 lru-cache 作为缓存适配器。

自定义共享适配器

如果你希望自己实现进程共享适配器,你需要:

  1. 确定进程间的通信方式。
  2. 实现 SyncAdapter 接口

具体而言,首先需要确定主进程与子进程之间的双向通信方式。例如,在 Node.js 中,alova 使用了 node-ipc 实现主进程和子进程的通信;在 Electron 中,则使用 ipcRendereripcMain 对象来实现。

随后,分别实现主进程和子进程的 SyncAdapter 接口,可通过 createSyncAdapter 提供类型帮助。

以下是一个在 Electron 中的实现:

import { createPSCSynchronizer, createSyncAdapter } from '@/sharedCacheAdapter';
import type { IpcMain, IpcRenderer } from 'electron';

const EventName = {
TO_MAIN: 'alova-ipc-to-main',
TO_CLIENT: 'alova-ipc-to-client'
} as const;

/**
* Use this function in payload.js
*/
export function MyElectronSyncAdapter(ipcRenderer: IpcRenderer) {
// createSyncAdapter is a helper to implement SyncAdapter. do nothing
return createSyncAdapter({
send(event) {
ipcRenderer.emit(EventName.TO_MAIN, event);
},
receive(handler) {
ipcRenderer.on(EventName.TO_CLIENT, (_, payload) => handler(payload));
}
});
}

let hasSynchronizer = false;

/**
* Use this function in main process.
*/
export function createMyElectronSharedCacheSynchronizer(ipcMain: IpcMain) {
if (hasSynchronizer) {
return;
}
hasSynchronizer = true;

createPSCSynchronizer(
createSyncAdapter({
send(event) {
ipcMain.emit(EventName.TO_CLIENT, event);
},
receive(handler) {
ipcMain.on(EventName.TO_MAIN, (_, payload) => handler(payload));
}
})
);
}

并参考上述示例使用即可。