|
| 1 | +# Databend Meta Control Lua API Documentation |
| 2 | + |
| 3 | +This document describes the Lua runtime API available in `databend-metactl lua` command. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The Lua runtime provides access to meta service operations through the `metactl` namespace. All functions and utilities are available in the global `metactl` table. |
| 8 | + |
| 9 | +## Core Functions |
| 10 | + |
| 11 | +### metactl.new_grpc_client(address) |
| 12 | + |
| 13 | +Creates a new gRPC client for communicating with the meta service. |
| 14 | + |
| 15 | +**Parameters:** |
| 16 | +- `address` (string): The gRPC address of the meta service (e.g., "127.0.0.1:9191") |
| 17 | + |
| 18 | +**Returns:** |
| 19 | +- A gRPC client object with methods for meta operations |
| 20 | + |
| 21 | +**Example:** |
| 22 | +```lua |
| 23 | +local client = metactl.new_grpc_client("127.0.0.1:9191") |
| 24 | +``` |
| 25 | + |
| 26 | +### metactl.spawn(function) |
| 27 | + |
| 28 | +Spawns an asynchronous task that runs concurrently. |
| 29 | + |
| 30 | +**Parameters:** |
| 31 | +- `function`: A Lua function to execute asynchronously |
| 32 | + |
| 33 | +**Returns:** |
| 34 | +- A task handle that can be awaited with `join()` |
| 35 | + |
| 36 | +**Example:** |
| 37 | +```lua |
| 38 | +local task = metactl.spawn(function() |
| 39 | + metactl.sleep(1.0) |
| 40 | + print("Task completed") |
| 41 | +end) |
| 42 | +task:join() |
| 43 | +``` |
| 44 | + |
| 45 | +### metactl.sleep(seconds) |
| 46 | + |
| 47 | +Asynchronously sleeps for the specified duration. |
| 48 | + |
| 49 | +**Parameters:** |
| 50 | +- `seconds` (number): Duration to sleep in seconds (supports fractional values) |
| 51 | + |
| 52 | +**Example:** |
| 53 | +```lua |
| 54 | +metactl.sleep(0.5) -- Sleep for 500ms |
| 55 | +metactl.sleep(2.0) -- Sleep for 2 seconds |
| 56 | +``` |
| 57 | + |
| 58 | +### metactl.to_string(value) |
| 59 | + |
| 60 | +Converts any Lua value to a human-readable string representation. |
| 61 | + |
| 62 | +**Parameters:** |
| 63 | +- `value`: Any Lua value (nil, boolean, number, string, table, etc.) |
| 64 | + |
| 65 | +**Returns:** |
| 66 | +- String representation of the value |
| 67 | + |
| 68 | +**Features:** |
| 69 | +- Handles nested tables recursively |
| 70 | +- Detects and converts byte vectors to strings |
| 71 | +- Sorts table keys for consistent output |
| 72 | +- Handles NULL values from meta service |
| 73 | +- Escapes quotes in strings |
| 74 | +- Single-line output format |
| 75 | + |
| 76 | +**Example:** |
| 77 | +```lua |
| 78 | +print(metactl.to_string({key="value", data={1,2,3}})) |
| 79 | +-- Output: {"data"={1,2,3},"key"="value"} |
| 80 | + |
| 81 | +print(metactl.to_string(metactl.NULL)) |
| 82 | +-- Output: NULL |
| 83 | +``` |
| 84 | + |
| 85 | +## Constants |
| 86 | + |
| 87 | +### metactl.NULL |
| 88 | + |
| 89 | +A special constant representing NULL values returned from the meta service. |
| 90 | + |
| 91 | +**Example:** |
| 92 | +```lua |
| 93 | +local result, err = client:get("nonexistent_key") |
| 94 | +if result == metactl.NULL then |
| 95 | + print("Key not found") |
| 96 | +end |
| 97 | +``` |
| 98 | + |
| 99 | +## gRPC Client Methods |
| 100 | + |
| 101 | +The client object returned by `metactl.new_grpc_client()` provides these methods: |
| 102 | + |
| 103 | +### client:get(key) |
| 104 | + |
| 105 | +Retrieves a value from the meta service. |
| 106 | + |
| 107 | +**Parameters:** |
| 108 | +- `key` (string): The key to retrieve |
| 109 | + |
| 110 | +**Returns:** |
| 111 | +- `result`: The retrieved value or `metactl.NULL` if not found |
| 112 | +- `error`: Error message string if operation failed, nil otherwise |
| 113 | + |
| 114 | +**Example:** |
| 115 | +```lua |
| 116 | +local client = metactl.new_grpc_client("127.0.0.1:9191") |
| 117 | +local result, err = client:get("my_key") |
| 118 | +if err then |
| 119 | + print("Error:", err) |
| 120 | +else |
| 121 | + print("Value:", metactl.to_string(result)) |
| 122 | +end |
| 123 | +``` |
| 124 | + |
| 125 | +### client:upsert(key, value) |
| 126 | + |
| 127 | +Inserts or updates a key-value pair in the meta service. |
| 128 | + |
| 129 | +**Parameters:** |
| 130 | +- `key` (string): The key to upsert |
| 131 | +- `value` (string): The value to store |
| 132 | + |
| 133 | +**Returns:** |
| 134 | +- `result`: Operation result containing sequence number and other metadata |
| 135 | +- `error`: Error message string if operation failed, nil otherwise |
| 136 | + |
| 137 | +**Example:** |
| 138 | +```lua |
| 139 | +local client = metactl.new_grpc_client("127.0.0.1:9191") |
| 140 | +local result, err = client:upsert("my_key", "my_value") |
| 141 | +if err then |
| 142 | + print("Error:", err) |
| 143 | +else |
| 144 | + print("Upsert result:", metactl.to_string(result)) |
| 145 | +end |
| 146 | +``` |
| 147 | + |
| 148 | +## Task Handling |
| 149 | + |
| 150 | +### task:join() |
| 151 | + |
| 152 | +Waits for a spawned task to complete and returns its result. |
| 153 | + |
| 154 | +**Returns:** |
| 155 | +- The return value of the spawned function |
| 156 | + |
| 157 | +**Example:** |
| 158 | +```lua |
| 159 | +local task = metactl.spawn(function() |
| 160 | + return "task result" |
| 161 | +end) |
| 162 | + |
| 163 | +local result = task:join() |
| 164 | +print(result) -- Output: task result |
| 165 | +``` |
| 166 | + |
| 167 | +## Usage Patterns |
| 168 | + |
| 169 | +### Basic Key-Value Operations |
| 170 | + |
| 171 | +```lua |
| 172 | +local client = metactl.new_grpc_client("127.0.0.1:9191") |
| 173 | + |
| 174 | +-- Store a value |
| 175 | +local upsert_result, err = client:upsert("config/timeout", "30") |
| 176 | +if not err then |
| 177 | + print("Stored successfully:", metactl.to_string(upsert_result)) |
| 178 | +end |
| 179 | + |
| 180 | +-- Retrieve a value |
| 181 | +local get_result, err = client:get("config/timeout") |
| 182 | +if not err then |
| 183 | + if get_result == metactl.NULL then |
| 184 | + print("Key not found") |
| 185 | + else |
| 186 | + print("Retrieved:", metactl.to_string(get_result)) |
| 187 | + end |
| 188 | +end |
| 189 | +``` |
| 190 | + |
| 191 | +### Concurrent Operations |
| 192 | + |
| 193 | +```lua |
| 194 | +local client = metactl.new_grpc_client("127.0.0.1:9191") |
| 195 | + |
| 196 | +local task1 = metactl.spawn(function() |
| 197 | + client:upsert("key1", "value1") |
| 198 | + print("Task 1 completed") |
| 199 | +end) |
| 200 | + |
| 201 | +local task2 = metactl.spawn(function() |
| 202 | + metactl.sleep(0.1) |
| 203 | + local result, _ = client:get("key1") |
| 204 | + print("Task 2 got:", metactl.to_string(result)) |
| 205 | +end) |
| 206 | + |
| 207 | +task1:join() |
| 208 | +task2:join() |
| 209 | +``` |
| 210 | + |
| 211 | +### Error Handling |
| 212 | + |
| 213 | +```lua |
| 214 | +local client = metactl.new_grpc_client("127.0.0.1:9191") |
| 215 | + |
| 216 | +local result, err = client:get("some_key") |
| 217 | +if err then |
| 218 | + print("Operation failed:", err) |
| 219 | + return |
| 220 | +end |
| 221 | + |
| 222 | +if result == metactl.NULL then |
| 223 | + print("Key does not exist") |
| 224 | +else |
| 225 | + print("Key value:", metactl.to_string(result)) |
| 226 | +end |
| 227 | +``` |
| 228 | + |
| 229 | +## Data Types |
| 230 | + |
| 231 | +The meta service returns structured data that can be processed using `metactl.to_string()`: |
| 232 | + |
| 233 | +```lua |
| 234 | +-- Typical get response structure: |
| 235 | +{ |
| 236 | + "data" = "actual_value", -- The stored value as byte array |
| 237 | + "seq" = 1 -- Sequence number |
| 238 | +} |
| 239 | + |
| 240 | +-- Typical upsert response structure: |
| 241 | +{ |
| 242 | + "result" = { |
| 243 | + "data" = "stored_value", |
| 244 | + "seq" = 1 |
| 245 | + } |
| 246 | +} |
| 247 | +``` |
| 248 | + |
| 249 | +## Best Practices |
| 250 | + |
| 251 | +1. **Always check for errors**: Both `get` and `upsert` operations can fail |
| 252 | +2. **Handle NULL values**: Use `metactl.NULL` comparison for missing keys |
| 253 | +3. **Use concurrent operations**: Leverage `metactl.spawn()` for parallel processing |
| 254 | +4. **Format output**: Use `metactl.to_string()` for readable data display |
| 255 | +5. **Clean resource usage**: Ensure tasks are properly joined |
| 256 | + |
| 257 | +## Examples |
| 258 | + |
| 259 | +See the test files in `tests/metactl/subcommands/` for comprehensive usage examples: |
| 260 | +- `cmd_lua_grpc.py` - Basic gRPC operations |
| 261 | +- `cmd_lua_spawn_grpc.py` - Concurrent gRPC operations |
| 262 | +- `cmd_lua_spawn_concurrent.py` - Task spawning patterns |
0 commit comments