Skip to content

Conversation

@marcj
Copy link
Owner

@marcj marcj commented Mar 7, 2025

feat(rpc): automatically garbage collect observables + new event system + stats collection

  • Fixed various soft memory leaks and hard to untangle circular references (making GC easier)

  • All observables are now tracked via WeakRef and FinalizationRegistry, and frees them up on the server automatically when the client garbage collected them.

    • previously it was required that all clients unsubscribe from observables and subjects otherwise there will always be a state on the server for these objects. now, the client can just use the received observable/subject and once they are no longer used (garbage collected by the javascript engine) the rpc client detects it and frees the resources on the server automatically.
  • Added new event system to track and control what the rpc kernel and connections do.
    onRpcConnection, onRpcConnectionClose, onRpcAction, onRpcAuth, onRpcControllerAccess

This not only allows to hook into various stages but also allows to replace RpcKernelSecurity for authentication and controller access:

const kernel = new RpcKernel();

kernel.listen(onRpcConnection, (event, logger: Logger) => {
    logger.log(`New Connection`);
});

kernel.listen(onRpcAction, (event, logger: Logger) => {
    logger.log(`action ${event.data.action}`, event.data.phase, event.data.timing);
});

kernel.listen(onRpcAuth, (event, logger: Logger) => {
    logger.log(`authenticating`);
    if (event.data.token === 'secret')  {
       event.data.session = new Session('Admin', '');
    }
});

kernel.listen(onRpcControllerAccess, (event, logger: Logger) => {
    logger.log(`authenticating`);
    if (event.data.session.username === 'Admin')  {
       event.data.granted = true;
    }
});
  • Added statistics object RpcStats which collects statistics about the kernel, traffic, connections, actions, and observables.
const kernel = new RpcKernel();

kernel.stats.connections // currently active connections
kernel.stats.totalConnections // all handled connections so far

kernel.stats.actions
kernel.stats.incomingBytes
kernel.stats.outgoingBytes

kernel.stats.active.observables //how many active observables there are
kernel.stats.active.subscriptions //how many observable subscriptions there are
// and more

also each RpcKernelConnection has a stats object with the same data

@marcj marcj force-pushed the feat/rpc-gc-events branch 2 times, most recently from 6e8894b to 74ddf07 Compare March 7, 2025 01:33
…em + stats collection

All observables are not tracked via WeakRef and FinalizationRegistry, and frees them up on the server automatically when the client garbage collected them.

Added new event system to track and control what the rpc kernel and connections do.

Added statistics object RpcStats which collects statistics about the kernel, traffic, connections, actions, and observables.
@marcj marcj force-pushed the feat/rpc-gc-events branch from 74ddf07 to d727232 Compare March 7, 2025 02:27
@marcus-sa
Copy link
Contributor

Nice work 🚀

@marcus-sa
Copy link
Contributor

@marcj is event no longer async?

@marcj
Copy link
Owner Author

marcj commented Mar 7, 2025

events are still async per default, but additionally you can now define sync events with EventTokenSync. this is helpful in cases where you want to dispatch events in a non-async function (like at some places in the rpc code). the signature of dispatch/listen changes depending on the EvenToken type

@marcj marcj changed the title rpc gc events feat(rpc): auto-GC observables, event system, statistics Mar 8, 2025
@marcj marcj merged commit dd6b9ea into master Mar 8, 2025
11 of 12 checks passed
@marcj marcj deleted the feat/rpc-gc-events branch March 13, 2025 00:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants