@kobayami/threads

Enables direct function calls from main thread into worker threads instead of manual message passing.

Usage no npm install needed!

<script type="module">
  import kobayamiThreads from 'https://cdn.skypack.dev/@kobayami/threads';
</script>

README

@kobayami/threads

Installation

npm install --save @kobayami/threads

Version and License

Summary

Enables direct function calls from main thread into worker threads instead of manual message passing. This simplifies the usage of worker threads a lot!

This library works for both Web and NodeJS environments and provides a common adapter API for the platform specific parts, so that the same application code can be run in both environments without modification.

Core features of this library include:

  • Direct function calls from main thread into services run on worker threads
  • Own very lightweight RMI protocol specifically for this purpose
  • Automatic handling of transfer objects
  • Support for synchronous and asynchronous service implementations
  • Compatible with Web and NodeJS environments

Usage Example

Service interface:

interface RenderService {
    enable(surface: OffscreenCanvas): Promise<void>;
    getSurface(): Promise<OffscreenCanvas | null>;
    setMaxFps(value: number): Promise<void>;
    getCurrentFps(): Promise<number>;
}

Main thread (main.js), or client side:

const renderService = createServiceRmiProxy<RenderService>(
    startWorker('./render.worker')
);

renderService.enable(new OffscreenCanvas(640, 480));
const canvas = await renderService.getSurface();
renderservice.setMaxFps(60);
delay(10);
const currentFps = await renderService.getCurrentFps();

Worker thread (render.worker.js), or server side:

class RenderServiceImpl implements RenderService {

    surface: OffscreenCanvas | null = null;
  
    maxFps = 60;
    
    lastRenderCycleTimeMs = Number.MAX_VALUE;
    
    async enable(surface: OffscreenCanvas): Promise<void> {
        this.surface = surface;
        this.startRenderLoop();
    }

    async getSurface(): Promise<OffscreenCanvas | null> {
        return this.surface;
    }
    
    async setMaxFps(value: number): Promise<void> {
        this.maxFps = value;
    }

    async getCurrentFps(): Promise<number> {
        return 1000 / this.lastRenderCycleTimeMs;
    }
    
    private startRenderLoop() {
        ...
    }
}

dispatchRmiRequestsSync(new RenderServiceImpl());

See Also