npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

rtjs-base

v0.9.0

Published

RT.js: A real-time capable pseudo-preemptive scheduler for JavaScript

Downloads

13

Readme

RT.js: Practical Real-Time Scheduling for Web Applications

RT.js is a framework that provides preemptive and prioritized scheduling of JavaScript jobs. JavaScript interpreters execute all jobs (i.e., event handlers) strictly in order and in a run-to-completion semantic. While a job is being executed, there is no way to yield the execution engine before the calculation has finished. Meanwhile, not only the JS-interpreter thread is blocked, but, more importantly, the rendering of the web page is delayed until the interpreter handed back control to the rendering engine. In fact, a JavaScript event handler may busy wait on something and starve all other jobs, the renderer of the browser tab, and the whole web page. We can see the effect of long running computations in a benchmark where computation-intense JS code is competing with UI update code for the interpreter. The benchmark can also be found here.

RT.js tackles this problem by inserting explicit preemption points into long-running JS functions via transpilation (i.e., source-to-source compiling) of the source code. We provide an abstraction to submit such transpiled functions as RT.js jobs with a given scheduling priority or with a relative execution deadline. The RT.js scheduler executes the given jobs according to their relative importance, periodically regains control over the interpreter by the inserted preemption points, and regularly returns to the browser, which then can decide what to do next (e.g., page rendering).

The transpiler achieves preemptability by converting every function marked with the @rtjs or // @rtjs decorator to a generator function, meaning that the run-time system allows returning from that function prematurely and re-entry into that function. The run-time system keeps the state of the function and the local objects. Preemption points are added by inserting yield-statements on the following occasions:

  • before while and for loop bodies, i.e. on every iteration of the loop
  • before function calls
  • before if statements

Both Mozilla and Google suggest either not using the main-thread (i.e. creating web workers for complex computations, with their own drawbacks) or splitting up the computations on the main thread. RT.js does that automatically and allows you to prioritize your work load. Compute intensive tasks can be offloaded to be executed when the RT.js scheduler runs next, whereas small event handlers can still be run without using the services of RT.js.

Conference Publication at RTSS 2019

RT.js: Practical Real-Time Scheduling for Web Applications. Christian Dietrich, Stefan Naumann, Robin Thrift, Daniel Lohmann. Proceedings of the 40th IEEE Real-Time Systems Symposium 2019. IEEE Computer Society Press. 2019

Project Directory Structure

  • src contains the main source files for the runtime and transpiler (source to source compiler).
  • src/transpiler contains the transpiler code.
  • benchmarks contains a number of benchmarks of different kinds.
    • benchmarks/qualitative is the macro benchmark from the RTSS publication. It contains a website running in a browser showcasing RT.js against the default run-to-completion policy of the JavaScript run-time engine. (you'll need plotly-base to use that benchmark).
    • benchmarks/minimal contains a small example project that uses RT.js to introduce pseudo-preemptivity.

After building the transpiler (see below), the build-folder exists, containing the transpiled RT.js library and the transpiler, ready for use.

Installation and Setup

  • npm install: Install all required dependencies (especially TypeScript).
  • make build: Build the RT.js transpiler. Please note: The benchmarks will build the transpiler as an dependency.
  • make docs: Generate a browsable version of the API docs in ./docs

Basic Usage

To allow for scheduling all tasks must inherit from the Task-class and override the run-method:

import { Task } from "Task"

class MyTask extends Task {
    // @rtjs
    *run() {
        var i = 0;
        while (i < 1000000) {
           i++;
        }
        // implement your task here
    }
}

Note that every method that should be transformed needs to be prefixed by the @rtjs-decorator. Functions can also be made schedulable and preemtible by simply prefixing them with the same @rtjs-decorator (or inside a comment for pure JavaScript // @rtjs).

To transpile the code use the rtjs-transpiler.js tool in build/transpiler, e.g.:

build/transpiler/rtjs-transpiler "MyTask.js"
cat build/MyTask.js

NOTE: Currently the output directory is always build