Skip to content

Commit

Permalink
Merge branch 'feature/v3.0.0' into next
Browse files Browse the repository at this point in the history
  • Loading branch information
MeetinaXD committed Jul 21, 2024
2 parents 7dcf0b1 + 10da6b6 commit dd8310b
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 26 deletions.
5 changes: 5 additions & 0 deletions .changeset/healthy-walls-boil.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@alova/psc': patch
---

fix: unable to establish ipc channel in node
8 changes: 6 additions & 2 deletions packages/psc/src/defaults/electronSyncAdapter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createPSCSynchronizer, createSyncAdapter } from '@/sharedCacheAdapter';
import { createPSCAdapter, createPSCSynchronizer, createSyncAdapter } from '@/sharedCacheAdapter';
import type { IpcMain, IpcRenderer } from 'electron';

const EventName = {
Expand All @@ -20,12 +20,16 @@ export function ElectronSyncAdapter(ipcRenderer: IpcRenderer) {
});
}

export function createElectronPSCAdapter(ipcRenderer: IpcRenderer) {
return createPSCAdapter(ElectronSyncAdapter(ipcRenderer));
}

let hasSynchronizer = false;

/**
* Use this function in main process.
*/
export function createElectronSharedCacheSynchronizer(ipcMain: IpcMain) {
export function createElectronPSCSynchronizer(ipcMain: IpcMain) {
if (hasSynchronizer) {
return;
}
Expand Down
14 changes: 11 additions & 3 deletions packages/psc/src/defaults/nodeSyncAdapter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createPSCSynchronizer, createSyncAdapter } from '@/sharedCacheAdapter';
import { createPSCAdapter, createPSCSynchronizer, createSyncAdapter } from '@/sharedCacheAdapter';
import { usePromise, uuid } from '@alova/shared/function';
import { QueueCallback } from '@alova/shared/queueCallback';
import { IPCModule as IPCModule_ } from '@node-ipc/node-ipc';
Expand All @@ -7,7 +7,7 @@ import type { IPC } from 'node-ipc';
// fix(type-issue): https://github.com/node-ipc/node-ipc/issues/4
const IPCModule = IPCModule_ as unknown as typeof IPC;

export const AlovaIPCID = uuid();
export const AlovaIPCID = 'alova-default-channel';

const EventName = {
TO_MAIN: 'alova-ipc-to-main',
Expand Down Expand Up @@ -44,6 +44,9 @@ export function NodeSyncAdapter(onConnect?: (stopFn: () => void) => void, id = A
});
});

// disconnect when the process is terminated.
process.on('SIGTERM', () => ipc.disconnect(id));

return createSyncAdapter({
send(event) {
queue.queueCallback(() => ipc.of[id]?.emit(EventName.TO_MAIN, event));
Expand All @@ -56,6 +59,10 @@ export function NodeSyncAdapter(onConnect?: (stopFn: () => void) => void, id = A
});
}

export function createNodePSCAdapter(onConnect?: (stopFn: () => void) => void, id = AlovaIPCID) {
return createPSCAdapter(NodeSyncAdapter(onConnect, id));
}

/**
* Use this function in main process.
*
Expand All @@ -64,7 +71,7 @@ export function NodeSyncAdapter(onConnect?: (stopFn: () => void) => void, id = A
* When running multiple synchronizers in main process, please assign `id` manually.
* And make sure the ids are unique between synchronizers
*/
export async function createNodeSharedCacheSynchronizer(id = AlovaIPCID) {
export async function createNodePSCSynchronizer(id = AlovaIPCID) {
const ipc = createIPC(id);

const { promise, resolve } = usePromise<() => void>();
Expand All @@ -87,6 +94,7 @@ export async function createNodeSharedCacheSynchronizer(id = AlovaIPCID) {
});

ipc.server.start();
process.on('SIGTERM', () => ipc.server.stop());

return promise;
}
22 changes: 18 additions & 4 deletions packages/psc/src/sharedCacheAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const createSyncAdapter = (syncAdapter: SyncAdapter) => syncAdapter;
* 2. Emit an event when the status changes.
* 3. Proxy the behavior of the incoming cacheAdapter.
*/
export class PSCAdapter implements AlovaGlobalCacheAdapter {
class ProcessSharedCacheAdapter implements AlovaGlobalCacheAdapter {
protected id = uuid();

protected queue = new QueueCallback();
Expand Down Expand Up @@ -182,15 +182,15 @@ export class ExplicitCacheAdapter implements AlovaGlobalCacheAdapter {
* )
* ```
*/
export function createPSCAdapter(
function createProcessSharedCacheAdapter(
syncAdapter: SyncAdapter,
cacheAdapter: AlovaGlobalCacheAdapter = new ExplicitCacheAdapter(),
options: ProcessSharedCacheAdapterOptions = {}
) {
return new PSCAdapter(cacheAdapter, syncAdapter, options);
return new ProcessSharedCacheAdapter(cacheAdapter, syncAdapter, options);
}

export function createPSCSynchronizer(syncAdapter: SyncAdapter) {
function createProcessSharedCacheSynchronizer(syncAdapter: SyncAdapter) {
const cache = new ExplicitCacheAdapter();
const cacheEventHandlers = {
set: (key: string, value?: any) => cache.set(key, value),
Expand Down Expand Up @@ -224,3 +224,17 @@ export function createPSCSynchronizer(syncAdapter: SyncAdapter) {
syncAdapter.send(newEvent);
});
}

// shorter alias
/**
* Alias of `ProcessSharedCacheAdapter`
*/
export const PSCAdapter = ProcessSharedCacheAdapter;
/**
* Alias of `createProcessSharedCacheAdapter`
*/
export const createPSCAdapter = createProcessSharedCacheAdapter;
/**
* Alias of `createProcessSharedCacheSynchronizer`
*/
export const createPSCSynchronizer = createProcessSharedCacheSynchronizer;
34 changes: 17 additions & 17 deletions packages/psc/test/sharedCache.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ElectronSyncAdapter, NodeSyncAdapter, createNodeSharedCacheSynchronizer } from '@/index';
import { NodeSyncAdapter, createElectronPSCAdapter, createNodePSCAdapter, createNodePSCSynchronizer } from '@/index';
import { ExplicitCacheAdapter, createPSCAdapter, createPSCSynchronizer, createSyncAdapter } from '@/sharedCacheAdapter';
import { key } from '@alova/shared/function';
import { forEach } from '@alova/shared/vars';
Expand Down Expand Up @@ -60,14 +60,14 @@ const prepareEnv = async () => {
id: 1
});

const { createElectronSharedCacheSynchronizer } = await import('@/defaults/electronSyncAdapter');
const { createElectronPSCSynchronizer } = await import('@/defaults/electronSyncAdapter');

return {
eventEmitter,
createSharedL1CacheAdapter,
createSharedCacheAlova,
createNonSharedCacheAlova,
createElectronSharedCacheSynchronizer
createElectronPSCSynchronizer
};
};

Expand Down Expand Up @@ -185,23 +185,23 @@ describe('shared cache', () => {
});

test('should share cache between same scope in Electron', async () => {
const { eventEmitter, createElectronSharedCacheSynchronizer } = await prepareEnv();
const { eventEmitter, createElectronPSCSynchronizer } = await prepareEnv();
const { ipcMain, ipcRenderer } = createFakeElectronExports(eventEmitter);

// simulate init operation in the main procress
createElectronSharedCacheSynchronizer(ipcMain);
createElectronPSCSynchronizer(ipcMain);

const alovaA = getAlovaInstance({
id: 1,
l1Cache: createPSCAdapter(ElectronSyncAdapter(ipcRenderer))
l1Cache: createElectronPSCAdapter(ipcRenderer)
});
const alovaB = getAlovaInstance({
id: 1,
l1Cache: createPSCAdapter(ElectronSyncAdapter(ipcRenderer))
l1Cache: createElectronPSCAdapter(ipcRenderer)
});
const alovaC = getAlovaInstance({
id: 2,
l1Cache: createPSCAdapter(ElectronSyncAdapter(ipcRenderer))
l1Cache: createElectronPSCAdapter(ipcRenderer)
});

const GetA = alovaA.Get('/unit-test', {
Expand All @@ -218,7 +218,7 @@ describe('shared cache', () => {

// should be only one synchronizer in electron
// so it takes no effect
createElectronSharedCacheSynchronizer(ipcMain);
createElectronPSCSynchronizer(ipcMain);
await delay(10);

expect(cache).not.toBeUndefined();
Expand All @@ -227,13 +227,13 @@ describe('shared cache', () => {
});

test('should set operation be a async function in electron', async () => {
const { eventEmitter, createElectronSharedCacheSynchronizer } = await prepareEnv();
const { eventEmitter, createElectronPSCSynchronizer } = await prepareEnv();
const { ipcMain, ipcRenderer, mainMockOn } = createFakeElectronExports(eventEmitter);

// simulate init operation in the main procress
createElectronSharedCacheSynchronizer(ipcMain);
createElectronPSCSynchronizer(ipcMain);

const l1Cache = createPSCAdapter(ElectronSyncAdapter(ipcRenderer));
const l1Cache = createElectronPSCAdapter(ipcRenderer);

const alovaA = getAlovaInstance({
id: 1,
Expand All @@ -255,21 +255,21 @@ describe('shared cache', () => {

test('should share cache between same scope in node', async () => {
// simulate init operation in the main procress
const stopServer = await createNodeSharedCacheSynchronizer();
const stopServer = await createNodePSCSynchronizer();

const stopHandler: (() => void)[] = [];

const alovaA = getAlovaInstance({
id: 1,
l1Cache: createPSCAdapter(NodeSyncAdapter(stop => stopHandler.push(stop)))
l1Cache: createNodePSCAdapter(stop => stopHandler.push(stop))
});
const alovaB = getAlovaInstance({
id: 1,
l1Cache: createPSCAdapter(NodeSyncAdapter(stop => stopHandler.push(stop)))
l1Cache: createNodePSCAdapter(stop => stopHandler.push(stop))
});
const alovaC = getAlovaInstance({
id: 2,
l1Cache: createPSCAdapter(NodeSyncAdapter(stop => stopHandler.push(stop)))
l1Cache: createNodePSCAdapter(stop => stopHandler.push(stop))
});

const GetA = alovaA.Get('/unit-test', {
Expand All @@ -290,7 +290,7 @@ describe('shared cache', () => {

test('should trigger event handler with expect times in node', async () => {
// simulate init operation in the main procress
const stopServer = await createNodeSharedCacheSynchronizer();
const stopServer = await createNodePSCSynchronizer();

const stopHandler: (() => void)[] = [];
const mockSend = jest.fn();
Expand Down

0 comments on commit dd8310b

Please sign in to comment.