Skip to content

src: optimizing watchdog performance

Performance of vm.Script's runInContext for small and/or quick scripts can be much slower when the optional execution timeout parameter is set - over 30 times slower in edge cases.

The root issue is the constant creation and destruction of threads. Each timeout is enforced with a parallel uv loop that contains a timer and for this a new uv thread is created and later destroyed.

For applications that utilize the vm for sandboxing it is often the case that the optional timeout will be frequently, if not always, set.

This is a small rework of the watchdog that will transform the uv loop into a single parallel thread for each execution thread.

Instead of spawning a thread for each watchdog instance a thread-local WatchdogService is used to execute the timer logic for all timeouts from the given execution thread. The WatchdogService is lazy-initialized the first time a watchdog is requested from an execution thread.

The uv_loop and uv_timers used by the Watchdog have been replaced by a multimap-based priority queue of WatchdogTimer objects. Timekeeping is done using uv_hrtime,

The WatchdogService::Run loop sleeps until the closest timeout is about to expire, or forever if there are no timers set. A conditional wait is used to notify the run loop of a new timer only if its expiration time is shorter than the current time the run loop is about to awaken.

Merge request reports

Loading