|
| 1 | +--- |
| 2 | +type: docs |
| 3 | +weight: 3 |
| 4 | +linkTitle: Functions |
| 5 | +title: Functions (FaaS) |
| 6 | +description: Deploy serverless functions using any language that compiles to WebAssembly for automatic scaling and event-driven execution |
| 7 | +keywords: |
| 8 | + - faas |
| 9 | + - functions |
| 10 | + - serverless |
| 11 | + - wasm |
| 12 | + - webassembly |
| 13 | + - triggers |
| 14 | + - http |
| 15 | + - pulsar |
| 16 | +--- |
| 17 | + |
| 18 | +Clever Functions execute in response to events (HTTP calls, Pulsar messages) without cold boot, in nanoseconds, while scaling automatically. Functions run in extra-light virtual machines using WebAssembly, providing strong isolation without containers. You can write Clever Functions in any language that compiles to WebAssembly (WASM/WASI), such as AssemblyScript, C, C++, Go, JavaScript, Rust or Zig. |
| 19 | + |
| 20 | +> [!NOTE] Clever Functions is in private access |
| 21 | +> Ask for activation to your sales representative or [Clever Cloud support](https://console.clever-cloud.com/ticket-center-choice) |
| 22 | +
|
| 23 | +## Key Features |
| 24 | + |
| 25 | +- Automatic scaling |
| 26 | +- WASI-compatible WASM runtime |
| 27 | +- Strong isolation without containers |
| 28 | +- Server-side compilation for supported languages |
| 29 | +- Event-driven execution via HTTP or Pulsar triggers |
| 30 | + |
| 31 | +## Server-side compilation |
| 32 | + |
| 33 | +For many languages, you don't have to compile your code to WASM yourself; just upload your source code and Clever Cloud's platform takes care of the rest. Supported languages and toolchains are: |
| 34 | + |
| 35 | +| Language | Toolchain | Platform code | Aliases | |
| 36 | +| -------------- | -------------------- | ---------------- | ------------ | |
| 37 | +| Rust | rustc | `rust` | — | |
| 38 | +| Go | TinyGo | `go` | `tinygo` | |
| 39 | +| AssemblyScript | asc | `assemblyscript` | `asc` | |
| 40 | +| JavaScript | QuickJS (customized) | `js` | `javascript` | |
| 41 | + |
| 42 | +## Architecture |
| 43 | + |
| 44 | +Functions use three core resources: |
| 45 | + |
| 46 | +| Resource | Description | Lifecycle | |
| 47 | +| -------------- | ----------------------------------------------------------------------------- | ------------------------------- | |
| 48 | +| **Function** | Configuration container (environment variables, memory limits, max instances) | Created once, updated as needed | |
| 49 | +| **Release** | A version of your WASM code stored in the registry | Created on each code upload | |
| 50 | +| **Deployment** | An active instance running a specific release | Created to make a release live | |
| 51 | + |
| 52 | +A Function can have multiple releases (code versions) and multiple deployments. Each deployment references exactly one release. |
| 53 | + |
| 54 | +```mermaid |
| 55 | +flowchart LR |
| 56 | + F[Function] -->|has many| D[Deployment] |
| 57 | + D -->|references| R[Release] |
| 58 | + F -->|has many| R |
| 59 | +``` |
| 60 | + |
| 61 | +### Deployment lifecycle |
| 62 | + |
| 63 | +When you deploy a Function, a client sends your WASM file to the control plane API, the registry stores the WASM and returns a release ID, the packager compiles WASM into an optimized executable binary, the scheduler selects the best worker based on current load, a worker downloads the binary and starts serving requests. Then, the Function is accessible via its HTTP endpoint: |
| 64 | + |
| 65 | +```mermaid |
| 66 | +sequenceDiagram |
| 67 | + participant client as Client |
| 68 | + participant API as Control Plane |
| 69 | + participant Packager |
| 70 | + participant Worker |
| 71 | + participant Cellar |
| 72 | +
|
| 73 | + Client->>API: Upload WASM + metadata |
| 74 | + API->>Cellar: Store WASM file |
| 75 | + API->>Packager: Compile to executable |
| 76 | + Packager->>Cellar: Store compiled binary |
| 77 | + Packager->>API: Ready to deploy |
| 78 | + API->>Worker: Deploy Function |
| 79 | + Worker->>Cellar: Download binary |
| 80 | + Worker-->>API: Deployment active |
| 81 | + API-->>Client: Deployment complete + URL |
| 82 | +``` |
| 83 | + |
| 84 | +### Workflow |
| 85 | + |
| 86 | +When you invoke a Function via HTTP, a request arrives at Clever Cloud's load balancer (Sōzu), is routed to an available worker based on Function configuration, then a worker executes your WASM binary in an isolated micro-VM. Finally, the response is returned to caller: |
| 87 | + |
| 88 | +```mermaid |
| 89 | +sequenceDiagram |
| 90 | + participant Client |
| 91 | + participant LB as Load Balancer |
| 92 | + participant Worker |
| 93 | + participant VM as WASM micro-VM |
| 94 | +
|
| 95 | + Client->>LB: HTTP Request |
| 96 | + LB->>Worker: Route to available worker |
| 97 | + Worker->>VM: Execute WASM |
| 98 | + VM-->>Worker: Output (stdout) |
| 99 | + Worker-->>Client: HTTP Response |
| 100 | +``` |
| 101 | + |
| 102 | +## Prerequisites |
| 103 | + |
| 104 | +To use Clever Functions you'll need : |
| 105 | +- An authorized access for your organisation |
| 106 | +- Clever Tools with Functions commands |
| 107 | + |
| 108 | +To check if you have access to Clever Functions for your organisation, run the following command in your terminal: |
| 109 | + |
| 110 | +```bash |
| 111 | +clever features enable functions |
| 112 | +clever kms --org <your_org_id> |
| 113 | +``` |
| 114 | + |
| 115 | +## Create a Function |
| 116 | + |
| 117 | +Create a new Function in your organization using `cleverctl`: |
| 118 | + |
| 119 | +```bash |
| 120 | +clever functions create --org <your_org_id> |
| 121 | +``` |
| 122 | + |
| 123 | +The response contains the `function_id` you'll use for all subsequent operations: |
| 124 | + |
| 125 | +```json |
| 126 | +{ |
| 127 | + "id": "function_id", |
| 128 | + "ownerId": "your_org_id", |
| 129 | + "environment": {}, |
| 130 | + "maxMemory": 67108864, |
| 131 | + "maxInstances": 1, |
| 132 | + "createdAt": "2023-06-24T21:29:25.898985Z", |
| 133 | + "updatedAt": "2023-06-24T21:29:25.898985Z" |
| 134 | +} |
| 135 | +``` |
| 136 | + |
| 137 | +### Set Environment Variables |
| 138 | + |
| 139 | +Pass environment variables to your Function at runtime: |
| 140 | + |
| 141 | +```bash |
| 142 | +clever functions set-env 'FOO=BAR,HELLO=WORLD' <function_id> --org <your_org_id> |
| 143 | +``` |
| 144 | + |
| 145 | +## Deploy a Function |
| 146 | + |
| 147 | +To deploy a Function using server-side compilation or pre-compiled WASM, use the `deploy` command: |
| 148 | + |
| 149 | +```bash |
| 150 | +clever functions deploy <source_file> <function_id> --org <your_org_id> |
| 151 | +clever functions deploy <wasm_file> <platform_code> <function_id> --org <your_org_id> |
| 152 | +``` |
| 153 | + |
| 154 | +During deployment, the platform handles multiple steps to ensure your Function is live and ready to serve requests: |
| 155 | +1. Uploads your code and creates a release |
| 156 | +2. Triggers server-side compilation if needed |
| 157 | +3. Creates a deployment referencing the release |
| 158 | +4. Schedules the deployment to available workers |
| 159 | + |
| 160 | +Once deployed, call your deployed Function via its HTTP endpoint: |
| 161 | + |
| 162 | +```bash |
| 163 | +curl https://functions-technical-preview.services.clever-cloud.com/<function_id> |
| 164 | +``` |
| 165 | + |
| 166 | +Functions receive data from `stdin` and send data through `stdout`. In debug mode, `stderr` and `dmesg` are also available. |
| 167 | + |
| 168 | +## Manage a Function and its deployments |
| 169 | + |
| 170 | +```bash |
| 171 | +# List all deployments for a Function to check their status: |
| 172 | +clever functions deploy list <function_id> --org <your_org_id> |
| 173 | + |
| 174 | +# Remove a specific deployment while keeping the Function: |
| 175 | +cleverctl functions deploy delete <function_id> <deployment_id> --org <your_org_id> |
| 176 | + |
| 177 | +# Delete the Function entirely along with all its deployments: |
| 178 | +cleverctl functions delete <function_id> --org <your_org_id> |
| 179 | +``` |
| 180 | + |
| 181 | +## Triggers |
| 182 | + |
| 183 | +Triggers define how Functions receives structured input and returns structured output. During private access phase, HTTP and Pulsar triggers are supported through JavaScript and Rust integrations. Future versions will adopt the WASM Component Model for broader compatibility. |
| 184 | + |
| 185 | +The HTTP trigger gives your Function access to the full HTTP request (body, headers, method) and lets it return a structured HTTP response. Append `?trigger=http` to the endpoint: |
| 186 | + |
| 187 | +``` |
| 188 | +https://functions-technical-preview.services.clever-cloud.com/<function_id>?trigger=http |
| 189 | +``` |
| 190 | + |
| 191 | +Here is a minimal example that returns the caller's User-Agent: |
| 192 | + |
| 193 | +```js |
| 194 | +function trigger_http(request) { |
| 195 | + return { |
| 196 | + status: 200, |
| 197 | + statusText: "OK", |
| 198 | + headers: { |
| 199 | + "Content-Type": "text/plain", |
| 200 | + "X-Powered-By": "CleverCloud", |
| 201 | + }, |
| 202 | + body: `User-Agent: ${request.headers["User-Agent"]}`, |
| 203 | + }; |
| 204 | +} |
| 205 | +``` |
| 206 | + |
| 207 | +## TCP Connections |
| 208 | + |
| 209 | +In private access phase, we support WASI 1.0 which can handle TCP connection but lacks socket opening Functions. Clever Functions will implement WASI 2.0 for full TCP support, but in the meantime, you can use host Functions we provide to fill this gap: |
| 210 | + |
| 211 | +```c |
| 212 | +void host_tcp_connect(char* address_ptr, size_t address_size, unsigned int flags, void* fd_ptr); |
| 213 | + |
| 214 | +// With TLS support |
| 215 | +void host_tls_connect(char* address_ptr, size_t address_size, char* hostname_ptr, size_t hostname_size, unsigned int flags, void* fd_ptr); |
| 216 | +``` |
| 217 | +
|
| 218 | +In JavaScript, the QuickJS toolchain gives you access to a higher-level API: |
| 219 | +
|
| 220 | +```js |
| 221 | +let socket = await net.WasiTcpConn.connect(address); |
| 222 | +``` |
| 223 | + |
| 224 | +## Troubleshooting |
| 225 | + |
| 226 | +Get detailed execution information by appending `?debug` to your Function URL: |
| 227 | + |
| 228 | +```bash |
| 229 | +curl "https://functions-technical-preview.services.clever-cloud.com/<function_id>?debug" |
| 230 | +``` |
| 231 | + |
| 232 | +Output: |
| 233 | + |
| 234 | +```json |
| 235 | +{ |
| 236 | + "stdout": "Hello Rust!\n", |
| 237 | + "stderr": "", |
| 238 | + "dmesg": "Start time: 2.202681ms\n\nWASI_FD_WRITE(vmctx=30c0ffee, 01, ffec8, 01, ffe9c)\n\tnwritten: 12\nHOST_HALT(vmctx=c000, 00)\n\tGRACEFULLY EXIT\n\nHalt reason: host_halt\n\n\tat 0x00001003: internal::graceful_exit\n\t\tmangled state: no valid stackframe found (rsp:00200010, rbp:00200008)\n\nRun time: 3.359928ms\nTotal time: 5.65287ms\n", |
| 239 | + "trigger": "Std", |
| 240 | + "responseBody": "", |
| 241 | + "currentPages": 17, |
| 242 | + "size": 2310144 |
| 243 | +} |
| 244 | +``` |
| 245 | + |
| 246 | +**Debug fields:** |
| 247 | + |
| 248 | +| Field | Description | |
| 249 | +| -------------- | ------------------------------------------------------------------------------ | |
| 250 | +| `stdout` | Standard output from the Function | |
| 251 | +| `stderr` | Error output from the Function | |
| 252 | +| `dmesg` | Debug messages including timing and WASI hostcall traces (similar to `strace`) | |
| 253 | +| `trigger` | Trigger type that executed the Function | |
| 254 | +| `responseBody` | HTTP response body (HTTP trigger only) | |
| 255 | +| `currentPages` | Memory pages used (4096 bytes each) | |
| 256 | +| `size` | WASM binary size in bytes | |
| 257 | + |
| 258 | +**Timing in `dmesg`:** `Start time` (init), `Run time` (execution), `Total time` (elapsed). |
0 commit comments