futriix/tests/modules/CMakeLists.txt
Ricardo Dias 6adef8e2f9
Adds support for scripting engines as Valkey modules (#1277)
This PR extends the module API to support the addition of different
scripting engines to execute user defined functions.

The scripting engine can be implemented as a Valkey module, and can be
dynamically loaded with the `loadmodule` config directive, or with the
`MODULE LOAD` command.

This PR also adds an example of a dummy scripting engine module, to show
how to use the new module API. The dummy module is implemented in
`tests/modules/helloscripting.c`.

The current module API support, only allows to load scripting engines to
run functions using `FCALL` command.

The additions to the module API are the following:

```c
/* This struct represents a scripting engine function that results from the
 * compilation of a script by the engine implementation. */
struct ValkeyModuleScriptingEngineCompiledFunction

typedef ValkeyModuleScriptingEngineCompiledFunction **(*ValkeyModuleScriptingEngineCreateFunctionsLibraryFunc)(
    ValkeyModuleScriptingEngineCtx *engine_ctx,
    const char *code,
    size_t timeout,
    size_t *out_num_compiled_functions,
    char **err);

typedef void (*ValkeyModuleScriptingEngineCallFunctionFunc)(
    ValkeyModuleCtx *module_ctx,
    ValkeyModuleScriptingEngineCtx *engine_ctx,
    ValkeyModuleScriptingEngineFunctionCtx *func_ctx,
    void *compiled_function,
    ValkeyModuleString **keys,
    size_t nkeys,
    ValkeyModuleString **args,
    size_t nargs);

typedef size_t (*ValkeyModuleScriptingEngineGetUsedMemoryFunc)(
    ValkeyModuleScriptingEngineCtx *engine_ctx);

typedef size_t (*ValkeyModuleScriptingEngineGetFunctionMemoryOverheadFunc)(
    void *compiled_function);

typedef size_t (*ValkeyModuleScriptingEngineGetEngineMemoryOverheadFunc)(
    ValkeyModuleScriptingEngineCtx *engine_ctx);

typedef void (*ValkeyModuleScriptingEngineFreeFunctionFunc)(
    ValkeyModuleScriptingEngineCtx *engine_ctx,
    void *compiled_function);

/* This struct stores the callback functions implemented by the scripting
 * engine to provide the functionality for the `FUNCTION *` commands. */
typedef struct ValkeyModuleScriptingEngineMethodsV1 {
    uint64_t version; /* Version of this structure for ABI compat. */

    /* Library create function callback. When a new script is loaded, this
     * callback will be called with the script code, and returns a list of
     * ValkeyModuleScriptingEngineCompiledFunc objects. */
    ValkeyModuleScriptingEngineCreateFunctionsLibraryFunc create_functions_library;

    /* The callback function called when `FCALL` command is called on a function
     * registered in this engine. */
    ValkeyModuleScriptingEngineCallFunctionFunc call_function;

    /* Function callback to get current used memory by the engine. */
    ValkeyModuleScriptingEngineGetUsedMemoryFunc get_used_memory;

    /* Function callback to return memory overhead for a given function. */
    ValkeyModuleScriptingEngineGetFunctionMemoryOverheadFunc get_function_memory_overhead;

    /* Function callback to return memory overhead of the engine. */
    ValkeyModuleScriptingEngineGetEngineMemoryOverheadFunc get_engine_memory_overhead;

    /* Function callback to free the memory of a registered engine function. */
    ValkeyModuleScriptingEngineFreeFunctionFunc free_function;
} ValkeyModuleScriptingEngineMethodsV1;

/* Registers a new scripting engine in the server.
 *
 * - `engine_name`: the name of the scripting engine. This name will match
 *   against the engine name specified in the script header using a shebang.
 *
 * - `engine_ctx`: engine specific context pointer.
 *
 * - `engine_methods`: the struct with the scripting engine callback functions
 * pointers.
 */
int ValkeyModule_RegisterScriptingEngine(ValkeyModuleCtx *ctx,
                                         const char *engine_name,
                                         void *engine_ctx,
                                         ValkeyModuleScriptingEngineMethods engine_methods);

/* Removes the scripting engine from the server.
 *
 * `engine_name` is the name of the scripting engine.
 *
 */
int ValkeyModule_UnregisterScriptingEngine(ValkeyModuleCtx *ctx, const char *engine_name);
```

---------

Signed-off-by: Ricardo Dias <ricardo.dias@percona.com>
2024-12-21 23:09:35 +01:00

60 lines
2.3 KiB
CMake

# Build test modules
list(APPEND MODULES_LIST "commandfilter")
list(APPEND MODULES_LIST "basics")
list(APPEND MODULES_LIST "testrdb")
list(APPEND MODULES_LIST "fork")
list(APPEND MODULES_LIST "infotest")
list(APPEND MODULES_LIST "propagate")
list(APPEND MODULES_LIST "misc")
list(APPEND MODULES_LIST "hooks")
list(APPEND MODULES_LIST "blockonkeys")
list(APPEND MODULES_LIST "blockonbackground")
list(APPEND MODULES_LIST "scan")
list(APPEND MODULES_LIST "datatype")
list(APPEND MODULES_LIST "datatype2")
list(APPEND MODULES_LIST "auth")
list(APPEND MODULES_LIST "keyspace_events")
list(APPEND MODULES_LIST "blockedclient")
list(APPEND MODULES_LIST "getkeys")
list(APPEND MODULES_LIST "getchannels")
list(APPEND MODULES_LIST "test_lazyfree")
list(APPEND MODULES_LIST "timer")
list(APPEND MODULES_LIST "defragtest")
list(APPEND MODULES_LIST "keyspecs")
list(APPEND MODULES_LIST "hash")
list(APPEND MODULES_LIST "zset")
list(APPEND MODULES_LIST "stream")
list(APPEND MODULES_LIST "mallocsize")
list(APPEND MODULES_LIST "aclcheck")
list(APPEND MODULES_LIST "list")
list(APPEND MODULES_LIST "subcommands")
list(APPEND MODULES_LIST "reply")
list(APPEND MODULES_LIST "cmdintrospection")
list(APPEND MODULES_LIST "eventloop")
list(APPEND MODULES_LIST "moduleconfigs")
list(APPEND MODULES_LIST "moduleconfigstwo")
list(APPEND MODULES_LIST "publish")
list(APPEND MODULES_LIST "usercall")
list(APPEND MODULES_LIST "postnotifications")
list(APPEND MODULES_LIST "moduleauthtwo")
list(APPEND MODULES_LIST "rdbloadsave")
list(APPEND MODULES_LIST "crash")
list(APPEND MODULES_LIST "cluster")
list(APPEND MODULES_LIST "helloscripting")
foreach (MODULE_NAME ${MODULES_LIST})
message(STATUS "Building test module: ${MODULE_NAME}")
add_library(${MODULE_NAME} SHARED "${CMAKE_SOURCE_DIR}/tests/modules/${MODULE_NAME}.c")
target_include_directories(${MODULE_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/src")
if (LINUX AND NOT APPLE)
# set the std to gnu11 here, to allow crash.c to get compiled
target_compile_options(${MODULE_NAME} PRIVATE "-std=gnu11")
endif ()
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
valkey_install_bin(${MODULE_NAME})
if (APPLE)
# Some symbols can only be resolved during runtime (they exist in the executable)
target_link_options(${MODULE_NAME} PRIVATE -undefined dynamic_lookup)
endif ()
endforeach ()