jsexecutor

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 28, 2025 License: Apache-2.0 Imports: 8 Imported by: 2

README

js-executor

English | 简体中文

Test codecov Go Report Card GoDoc

JavaScript execution thread pool for Go with 100% test coverage.

Overview

js-executor is a high-performance, flexible JavaScript execution pool for Go.
It provides a thread pool model for executing JavaScript code in parallel, running each engine instance in a native OS thread.
It supports pluggable engine backends (such as QuickJS), initialization scripts, context passing, and robust resource management.

Supported Engines

Engine Repository
QuickJS github.com/buke/quickjs-go

Features

  • Thread Pool Model: Efficiently handles multiple JavaScript tasks in parallel using native threads.
  • Pluggable Engine Support: Easily integrates with different JavaScript engines (e.g., QuickJS).
  • Initialization Scripts: Supports loading and reloading of initialization scripts for all threads.
  • Context Passing: Allows passing custom context data with each request and response.
  • Resource Management: Automatic thread lifecycle management, including idle timeout and max execution limits.
  • Timeout and Limits: Configurable execution timeout, memory limit, stack size, and more.
  • Cross-Platform: Works on Linux, macOS, and Windows.
  • 100% Test Coverage: All core modules and engine options are fully tested.

Usage Example

import (
    "fmt"
    jsexecutor "github.com/buke/js-executor"
    quickjsengine "github.com/buke/js-executor/engines/quickjs-go"
)

func main() {
    // Prepare an initialization script
    initScript := &jsexecutor.InitScript{
        FileName: "hello.js",
        Content:  `function hello(name) { return "Hello, " + name + "!"; }`,
    }

    // Create a new executor with QuickJS engine
    executor, err := jsexecutor.NewExecutor(
        jsexecutor.WithJsEngine(quickjsengine.NewFactory()),
        jsexecutor.WithInitScripts(initScript),
    )
    if err != nil {
        panic(err)
    }
    defer executor.Stop()

    // Start the executor
    if err := executor.Start(); err != nil {
        panic(err)
    }

    // Execute a JS function
    req := &jsexecutor.JsRequest{
        Id:      "1",
        Service: "hello",
        Args:    []interface{}{"World"},
    }
    resp, err := executor.Execute(req)
    if err != nil {
        panic(err)
    }
    fmt.Println(resp.Result) // Output: Hello, World!
}

Configuration

  • Pool Size: Set minimum and maximum thread pool size.
  • Queue Size: Set per-thread task queue size.
  • Timeouts: Configure execution timeout, thread idle timeout, and max executions per thread.
  • Engine Options: Configure memory limit, stack size, GC threshold, module import, etc.

Quick Start

  1. Install dependencies:

    go get github.com/buke/js-executor
    go get github.com/buke/js-executor/engines/quickjs-go
    
  2. See example_test.go for more usage examples.

License

Apache-2.0

Documentation

Overview

Example

Example demonstrates how to use JsExecutor with QuickJS engine. It shows how to initialize the executor, start it, execute a simple JS function, and stop the executor.

package main

import (
	"fmt"

	jsexecutor "github.com/buke/js-executor"
	quickjsengine "github.com/buke/js-executor/engines/quickjs-go"
)

func main() {
	// Prepare a simple JS function as an initialization script
	initScript := &jsexecutor.InitScript{
		FileName: "hello.js",
		Content:  `function hello(name) { return "Hello, " + name + "!"; }`,
	}

	// Create a QuickJS engine builder and a new executor with the init script
	executor, err := jsexecutor.NewExecutor(
		jsexecutor.WithJsEngine(quickjsengine.NewFactory(
			quickjsengine.WithEnableModuleImport(true),
			quickjsengine.WithCanBlock(true),
		)),
		jsexecutor.WithInitScripts(initScript),
	)
	if err != nil {
		fmt.Printf("Failed to create executor: %v\n", err)
		return
	}

	// Start the executor
	if err := executor.Start(); err != nil {
		fmt.Printf("Failed to start executor: %v\n", err)
		return
	}

	// Prepare a JS request to call the hello function
	req := &jsexecutor.JsRequest{
		Id:      "1",
		Service: "hello",
		Args:    []interface{}{"World"},
	}

	// Execute the JS request
	resp, err := executor.Execute(req)
	if err != nil {
		fmt.Printf("Execution error: %v\n", err)
		return
	}
	fmt.Printf("Result: %v\n", resp.Result)

	// Stop the executor
	if err := executor.Stop(); err != nil {
		fmt.Printf("Failed to stop executor: %v\n", err)
		return
	}

}
Output:

Result: Hello, World!

Index

Examples

Constants

View Source
const ThreadIdKey = "__threadId"

ThreadIdKey is the context key for specifying thread ID in requests.

Variables

This section is empty.

Functions

func WithCreateThreshold

func WithCreateThreshold(threshold float64) func(*JsExecutor)

WithCreateThreshold sets the queue load threshold for creating new threads.

func WithExecuteTimeout

func WithExecuteTimeout(timeout time.Duration) func(*JsExecutor)

WithExecuteTimeout sets the timeout for task execution.

func WithInitScripts

func WithInitScripts(scripts ...*InitScript) func(*JsExecutor)

WithInitScripts configures the initialization scripts.

func WithJsEngine

func WithJsEngine(engineFactory JsEngineFactory) func(*JsExecutor)

WithJsEngine configures the JavaScript engine builder and options.

func WithLogger

func WithLogger(logger *slog.Logger) func(*JsExecutor)

WithLogger configures the logger for the executor.

func WithMaxExecutions

func WithMaxExecutions(max uint32) func(*JsExecutor)

WithMaxExecutions sets the maximum executions per thread before cleanup.

func WithMaxPoolSize

func WithMaxPoolSize(size uint32) func(*JsExecutor)

WithMaxPoolSize sets the maximum number of threads in the pool.

func WithMinPoolSize

func WithMinPoolSize(size uint32) func(*JsExecutor)

WithMinPoolSize sets the minimum number of threads in the pool.

func WithQueueSize

func WithQueueSize(size uint32) func(*JsExecutor)

WithQueueSize sets the size of the task queue per thread.

func WithSelectThreshold

func WithSelectThreshold(threshold float64) func(*JsExecutor)

WithSelectThreshold sets the queue load threshold for skipping busy threads.

func WithThreadTTL

func WithThreadTTL(ttl time.Duration) func(*JsExecutor)

WithThreadTTL sets the time-to-live for idle threads.

Types

type InitScript

type InitScript struct {
	Content  string // Script content
	FileName string // Script file name for debugging purposes
}

InitJsScript represents a JavaScript initialization script

type JsEngine

type JsEngine interface {
	// Init initializes the engine with the given scripts
	Init(scripts []*InitScript) error

	// Reload reloads the engine with new scripts
	Reload(scripts []*InitScript) error

	// Execute executes a JavaScript request and returns the response
	Execute(req *JsRequest) (*JsResponse, error)

	// Close closes the engine and releases resources
	Close() error
}

JsEngine represents a JavaScript execution engine

type JsEngineFactory

type JsEngineFactory func() (JsEngine, error)

JsEngineFactory defines a function type for creating JavaScript engines

type JsExecutor

type JsExecutor struct {
	// contains filtered or unexported fields
}

JsExecutor manages a pool of JavaScript execution threads.

func NewExecutor

func NewExecutor(opts ...func(*JsExecutor)) (*JsExecutor, error)

NewExecutor creates a new JavaScript executor with the given options.

func (*JsExecutor) Execute

func (e *JsExecutor) Execute(request *JsRequest) (*JsResponse, error)

Execute executes a JavaScript request and returns the response.

func (*JsExecutor) Reload

func (e *JsExecutor) Reload(scripts ...*InitScript) error

Reload reloads all threads with new initialization scripts.

func (*JsExecutor) Start

func (e *JsExecutor) Start() error

Start initializes and starts the executor thread pool.

func (*JsExecutor) Stop

func (e *JsExecutor) Stop() error

Stop stops the executor and shuts down all threads.

type JsExecutorOption

type JsExecutorOption struct {
	// contains filtered or unexported fields
}

JsExecutorOption contains configuration options for the JavaScript executor.

type JsRequest

type JsRequest struct {
	Id      string                 `json:"id"`      // Unique identifier for the request
	Service string                 `json:"service"` // Service/function name to call
	Args    []interface{}          `json:"args"`    // Arguments to pass to the function
	Context map[string]interface{} `json:"context"` // Additional context data
}

JsRequest represents a JavaScript execution request

type JsResponse

type JsResponse struct {
	Id      string                 `json:"id"`      // Request ID that this response corresponds to
	Result  interface{}            `json:"result"`  // Execution result
	Context map[string]interface{} `json:"context"` // Updated context data
}

JsResponse represents the result of JavaScript execution

Directories

Path Synopsis
engines

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL