Skip to content

Add Static Module Support#3392

Merged
ranshid merged 24 commits into
valkey-io:unstablefrom
eifrah-aws:static-lua
Apr 20, 2026
Merged

Add Static Module Support#3392
ranshid merged 24 commits into
valkey-io:unstablefrom
eifrah-aws:static-lua

Conversation

@eifrah-aws

@eifrah-aws eifrah-aws commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

Add a build option to compile the Lua scripting engine as a static module and wire the server to load it directly at startup when enabled. The module load path now resolves on-load and on-unload entry points from the main binary, and the module lifecycle keeps those callbacks so unload works without a shared library handle.

The Lua module build was updated to support both static and shared variants, with the static path exporting visible wrapper symbols and linking the server with the module archive. While touching the Lua code, a few internal symbols were renamed for consistency and the monotonic time helper was clarified.

Note that this PR addresses the LUA module, but it can be applied to other "core" modules (like: Bloom, Json, Search and others). With this change, it will be easier to ship Valkey bundle with modules.

Areas touched:

  • CMake
  • Makefile
  • Lua scripting module
  • Core module loading

Generated by CodeLite

Add a build option to compile the Lua scripting engine as a static module and
wire the server to load it directly at startup when enabled. The module load
path now resolves on-load and on-unload entry points from the main binary, and
the module lifecycle keeps those callbacks so unload works without a shared
library handle.

The Lua module build was updated to support both static and shared variants,
with the static path exporting visible wrapper symbols and linking the server
with the module archive. While touching the Lua code, a few internal symbols
were renamed for consistency and the monotonic time helper was clarified.

* CMake
* Makefile
* Lua scripting module
* Core module loading

**Generated by CodeLite**

Signed-off-by: Eran Ifrah <eifrah@amazon.com>
@codecov

codecov Bot commented Mar 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 52.80899% with 42 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.39%. Comparing base (b2e0f63) to head (68a09c7).

Files with missing lines Patch % Lines
src/module.c 51.72% 42 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           unstable    #3392      +/-   ##
============================================
- Coverage     76.45%   76.39%   -0.07%     
============================================
  Files           159      159              
  Lines         79840    79879      +39     
============================================
- Hits          61042    61022      -20     
- Misses        18798    18857      +59     
Files with missing lines Coverage Δ
src/config.c 78.09% <100.00%> (-0.24%) ⬇️
src/eval.c 91.50% <ø> (ø)
src/module.h 0.00% <ø> (ø)
src/server.c 89.60% <100.00%> (+0.10%) ⬆️
src/module.c 25.53% <51.72%> (-0.36%) ⬇️

... and 24 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ranshid ranshid added the run-extra-tests Run extra tests on this PR (Runs all tests from daily except valgrind and RESP) label Mar 23, 2026
@ranshid

ranshid commented Mar 23, 2026

Copy link
Copy Markdown
Member

No deep dive yet.

I think we need to clarify requirements before proceeding with a deep dive.

The original change aimed to:

  1. Enable users to define and use new scripting engines (e.g., LuaJIT, JavaScript)
  2. Allow users who don't use script commands (EVAL, EVALSHA) to compile and run Valkey without Lua support, avoiding frequent patching for Lua library vulnerabilities

For the 9.1 release, we must decide:

  1. Legacy Lua load/unload support: Should we support dynamically loading/unloading Lua? The current implementation allows unloading Lua (though it remains in the binary) to replace it with a different Lua module. This could enable users to dynamically "patch" Lua, but the old module persists in the code. Does this provide meaningful value?

  2. Observability: The new Lua currently appears in the module list. This may impact installations that verify module list output. This decision depends on /1 if Lua cannot be dynamically loaded/unloaded, should we list it like other modules?

@ranshid ranshid self-requested a review March 23, 2026 13:18
Comment thread src/modules/lua/script_lua.c Outdated
@madolson madolson moved this to Todo in Valkey 9.1 Mar 23, 2026
@madolson

Copy link
Copy Markdown
Member

Core team discussion:

  1. Is this is an important thing to do in 9.1?
    1. We think it's important for 9.1.
  2. We are fine with having the same observability.
  3. We are fine with unloading and not being able to reload it.
  4. If it's statically linked it's loaded automatically. If it's not statically linked it's not loaded automatically.
  5. Statically linked will the default. Review the makefile variable so that it's similar with TLS and RDMA.

@valkey-io/core-team and @rjd15372 specifically in case you have some thoughts.

See #2858 (comment) for some additional discussion.

When a scripting engine is unregistered, its cached eval scripts are now
removed as well. This prevents the eval cache from holding dangling
references to the engine after it has been unloaded.

The eval subsystem now exposes a helper for deleting all scripts owned by
a specific engine, updates the eval cache bookkeeping as entries are
removed, and logs how many scripts were cleaned up during engine
unregistration.

* scripting_engine
* eval

**Generated by CodeLite**

Signed-off-by: Eran Ifrah <eifrah@amazon.com>
@eifrah-aws eifrah-aws marked this pull request as ready for review March 25, 2026 15:51
Update the Lua module to use the engine-provided monotonic clock helper when
built with STATIC_LUA, while keeping the module's local implementation for
non-static builds.

This avoids duplicate timing implementations and keeps elapsed-time handling
consistent across build configurations.

* Lua module
* Static build integration

**Generated by CodeLite**

Signed-off-by: Eran Ifrah <eifrah@amazon.com>
The server startup path now only auto-loads Lua at runtime for the static
build.

Consolidate Lua scripting engine build configuration around a single BUILD_LUA
value with explicit static, module, and no modes. This removes the separate
BUILD_STATIC_LUA toggle and updates the build system to derive compile
definitions, link behavior, and module packaging from the selected mode.

* Build system
* Server startup
* Lua module packaging

**Generated by CodeLite**

Signed-off-by: Eran Ifrah <eifrah@amazon.com>
* Build system

**Generated by CodeLite**

Signed-off-by: Eran Ifrah <eifrah@amazon.com>
@ranshid

ranshid commented Mar 26, 2026

Copy link
Copy Markdown
Member

@eifrah-aws please check the CI failures

Adjust the module API hook test to inspect a larger tail of the replica log when verifying the shutdown event. This makes the assertion less brittle and better aligned with the amount of output produced during shutdown.

**Generated by CodeLite**

Signed-off-by: Eran Ifrah <eifrah@amazon.com>
The extra log line caused an error to some of the TCL tests.

Signed-off-by: Eran Ifrah <eifrah@amazon.com>

@ranshid ranshid left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks very good!

One high level comment I have is the lack of good testing. Can we place some tests that verify statoc AND dynamic lua are not breaking to load/unload and that the engine can start without a lua engine (also when eval/evalsha are being generated)?

Comment thread src/modules/lua/Makefile
Comment thread src/modules/lua/Makefile
Comment thread src/modules/lua/script_lua.c Outdated
In addition, removed duplicate code.
Minor fix in the Makefile: settings LUA_MODULE_NAME to its correct name.

Signed-off-by: Eran Ifrah <eifrah@amazon.com>
Signed-off-by: Eran Ifrah <eifrah@amazon.com>

@zuiderkwast zuiderkwast left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good in general, but it seems the visibility attributes things are not finalized?

Comment thread src/module.c Outdated
Signed-off-by: Eran Ifrah <eifrah@amazon.com>
Update the documentation comments for the static module loading helpers to better match Valkey's standard.

* API docs

**Generated by CodeLite**

Signed-off-by: Eran Ifrah <eifrah@amazon.com>
Comment thread src/module.c
Comment thread src/modules/lua/script_lua.c Outdated
Comment thread src/scripting_engine.c Outdated
Comment thread src/modules/lua/function_lua.c
Extract the common module initialization logic from `moduleLoad` and `moduleLoadStatic` into a new helper function `moduleInitPostOnLoadResolved`. This function handles the shared workflow of invoking the onload callback, registering the module, performing post-load validation, and firing server events.

The refactoring eliminates approximately 70 lines of duplicated code while preserving all existing behavior. The helper function accepts parameters that control static vs. dynamic module handling, including whether to close the dlopen handle and how to format log messages.

Both `moduleLoad` and `moduleLoadStatic` now focus on their specific responsibilities (dlopen/symbol resolution) and delegate the common initialization sequence to the shared helper.

* Module loading infrastructure
* Code deduplication

**Generated by CodeLite**

Signed-off-by: Eran Ifrah <eifrah@amazon.com>
- Move `evalRemoveScriptsOfEngine` code to a separate PR
- Renamed `lua_scripts_flags_def` -> `lua_scripts_flags` with `static`

Signed-off-by: Eran Ifrah <eifrah@amazon.com>
When building static lua, use:

- `getMonotonicUs()`
- `elapsedUs`
- `elapsedMs`

from the engine's `monotonic.h` header.

Signed-off-by: Eran Ifrah <eifrah@amazon.com>
@eifrah-aws eifrah-aws requested a review from madolson April 16, 2026 14:24

@madolson madolson left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay. The tests all seem unrelated, but lgtm

@eifrah-aws

Copy link
Copy Markdown
Contributor Author

Sorry for the delay. The tests all seem unrelated, but lgtm

Thanks, for the review. I have updated the branch to the latest unstable.

@ranshid ranshid merged commit 0327c27 into valkey-io:unstable Apr 20, 2026
60 of 64 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to To be backported in Valkey 9.1 Apr 20, 2026
@zuiderkwast

Copy link
Copy Markdown
Contributor

Forgot to update README.md with the build options?

sarthakaggarwal97 pushed a commit to sarthakaggarwal97/valkey that referenced this pull request Apr 23, 2026
Add a build option to compile the Lua scripting engine as a static
module and wire the server to load it directly at startup when enabled.
The module load path now resolves on-load and on-unload entry points
from the main binary, and the module lifecycle keeps those callbacks so
unload works without a shared library handle.

The Lua module build was updated to support both static and shared
variants, with the static path exporting visible wrapper symbols and
linking the server with the module archive. While touching the Lua code,
a few internal symbols were renamed for consistency and the monotonic
time helper was clarified.

Note that this PR addresses the LUA module, but it can be applied to
other "core" modules (like: Bloom, Json, Search and others). With this
change, it will be easier to ship Valkey bundle with modules.

Areas touched:

* CMake
* Makefile
* Lua scripting module
* Core module loading

**Generated by CodeLite**

---------

Signed-off-by: Eran Ifrah <eifrah@amazon.com>
madolson pushed a commit that referenced this pull request Apr 27, 2026
Add a build option to compile the Lua scripting engine as a static
module and wire the server to load it directly at startup when enabled.
The module load path now resolves on-load and on-unload entry points
from the main binary, and the module lifecycle keeps those callbacks so
unload works without a shared library handle.

The Lua module build was updated to support both static and shared
variants, with the static path exporting visible wrapper symbols and
linking the server with the module archive. While touching the Lua code,
a few internal symbols were renamed for consistency and the monotonic
time helper was clarified.

Note that this PR addresses the LUA module, but it can be applied to
other "core" modules (like: Bloom, Json, Search and others). With this
change, it will be easier to ship Valkey bundle with modules.

Areas touched:

* CMake
* Makefile
* Lua scripting module
* Core module loading

**Generated by CodeLite**

---------

Signed-off-by: Eran Ifrah <eifrah@amazon.com>
sarthakaggarwal97 added a commit to sarthakaggarwal97/valkey that referenced this pull request Apr 27, 2026
…sers)

Removed valkey-io#3504, valkey-io#3545, valkey-io#3503 - these fix bugs introduced by valkey-io#3324, valkey-io#2936,

Signed-off-by: Sarthak Aggarwal <sarthagg@amazon.com>
valkey-io#3392 respectively, all new in RC2. Users never experienced these bugs.
@sarthakaggarwal97 sarthakaggarwal97 added the release-notes This issue should get a line item in the release notes label Apr 28, 2026
@eifrah-aws eifrah-aws deleted the static-lua branch May 11, 2026 08:25
@sarthakaggarwal97 sarthakaggarwal97 moved this from To be backported to Done in Valkey 9.1 May 16, 2026
@eifrah-aws eifrah-aws restored the static-lua branch June 1, 2026 07:36
@eifrah-aws eifrah-aws deleted the static-lua branch June 1, 2026 07:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-notes This issue should get a line item in the release notes run-extra-tests Run extra tests on this PR (Runs all tests from daily except valgrind and RESP)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants