Skip to content
/ silly Public

Lightweight, high-performance Lua network framework. Supports TCP, UDP, WebSocket, gRPC, Redis, MySQL, Prometheus, and etcd v3. Includes SSL/TLS and a built-in debugger.

License

Notifications You must be signed in to change notification settings

findstr/silly

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Silly

A Lightweight, High-Performance Server Framework for Lua

License CI Documentation

English | ็ฎ€ไฝ“ไธญๆ–‡

Features โ€ข Quick Start โ€ข Examples โ€ข Documentation โ€ข Contributing


โœจ Features

  • ๐Ÿš€ High Performance - Handles 200,000+ requests/second with single-threaded architecture
  • ๐Ÿงต Coroutine-Based - Clean async/await style code without callback hell
  • ๐ŸŒ Rich Protocols - Built-in support for TCP, UDP, HTTP, WebSocket, gRPC, TLS
  • ๐Ÿ’พ Database Ready - Native MySQL, Redis, and Etcd integrations
  • ๐Ÿ” Security - Comprehensive crypto suite including JWT, AES, RSA, HMAC
  • ๐Ÿ“Š Observability - Prometheus metrics and structured logging out of the box
  • ๐Ÿ”ง Developer Friendly - Hot reload, interactive debugger, and extensive APIs

๐Ÿš€ Quick Start

Installation

# Clone the repository
git clone https://github.com/findstr/silly.git
cd silly

# Build (supports Linux, macOS, Windows)
make

# With OpenSSL support for TLS
make OPENSSL=ON

Hello World

Create a file hello.lua:

local tcp = require "silly.net.tcp"

tcp.listen("127.0.0.1:8888", function(conn)
    print("New connection from", conn:remoteaddr())

    while true do
        local data = conn:read("\n")
        if not data then
            print("Client disconnected")
            break
        end

        conn:write("Echo: " .. data)
    end
    conn:close()
end)

print("Server listening on 127.0.0.1:8888")

Run the server:

./silly hello.lua

Test with telnet or netcat:

echo "Hello Silly!" | nc localhost 8888

๐Ÿ“Š Performance

Benchmarked on Intel Core i7-10700 @ 2.90GHz using redis-benchmark:

Test Throughput (req/s) Avg Latency P99 Latency
PING_INLINE 235,849 0.230ms 0.367ms
PING_MBULK 224,719 0.241ms 0.479ms

View Full Benchmark Results โ†’

๐ŸŽฏ Examples

HTTP Server

local silly = require "silly"
local http = require "silly.net.http"

http.listen {
    addr = "0.0.0.0:8080",
    handler = function(stream)
        local response_body = "Hello from Silly!"
        stream:respond(200, {
            ["content-type"] = "text/plain",
            ["content-length"] = #response_body,
        })
        stream:close(response_body)
    end
}

print("HTTP server listening on http://0.0.0.0:8080")

WebSocket Chat

local websocket = require "silly.net.websocket"

websocket.listen {
    addr = "0.0.0.0:8080",
    handler = function(sock)
        print("Client connected:", sock.fd)

        while true do
            local data, typ = sock:read()
            if not data or typ == "close" then
                break
            end

            if typ == "text" then
                sock:write("Echo: " .. data, "text")
            end
        end

        sock:close()
    end
}

print("WebSocket server listening on ws://0.0.0.0:8080")

MySQL Query

local silly = require "silly"
local mysql = require "silly.store.mysql"

local db = mysql.open {
    addr = "127.0.0.1:3306",
    user = "root",
    password = "password",
    database = "mydb",
    charset = "utf8mb4",
    max_open_conns = 10,
    max_idle_conns = 5,
}

silly.fork(function()
    local users, err = db:query("SELECT * FROM users WHERE age > ?", 18)
    if users then
        for _, user in ipairs(users) do
            print(user.name, user.email)
        end
    else
        print("Query failed:", err.message)
    end

    db:close()
end)

For more examples, check out the tutorials in the documentation.

๐Ÿ“š Documentation

Comprehensive documentation is available at https://findstr.github.io/silly/

๐Ÿ—๏ธ Architecture

Silly uses a hybrid threading model for optimal performance:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                   Silly Framework                    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Worker Threadโ”‚ Socket Threadโ”‚ Timer Thread โ”‚Monitor โ”‚
โ”‚  (Lua VM)    โ”‚ (epoll/kqueueโ”‚  (10ms res)  โ”‚ Thread โ”‚
โ”‚              โ”‚  /iocp)      โ”‚              โ”‚        โ”‚
โ”‚ โ€ข Coroutine  โ”‚ โ€ข I/O Events โ”‚ โ€ข Timers     โ”‚โ€ข Healthโ”‚
โ”‚ โ€ข Business   โ”‚ โ€ข 65K conns  โ”‚ โ€ข Schedulers โ”‚  Check โ”‚
โ”‚   Logic      โ”‚              โ”‚              โ”‚        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Key design principles:

  • Single-threaded business logic - No locks, no race conditions
  • Asynchronous I/O - Event-driven socket operations
  • Coroutine-based - Clean async code without callbacks

๐Ÿ”Œ Core Modules

Module Description Documentation
silly.net TCP, UDP, HTTP, WebSocket, gRPC, TLS API
silly.store MySQL, Redis, Etcd API
silly.crypto AES, RSA, HMAC, Hash API
silly.sync Channel, Mutex, WaitGroup API
silly.security JWT authentication API
silly.metrics Prometheus metrics API
silly.logger Structured logging API

๐Ÿ› ๏ธ Advanced Usage

Command Line Options

./silly main.lua [options]

Core Options:
  -h, --help                Display help message
  -v, --version             Show version
  -d, --daemon              Run as daemon

Logging:
  -p, --logpath PATH        Log file path
  -l, --loglevel LEVEL      Log level (debug/info/warn/error)
  -f, --pidfile FILE        PID file path

Custom Options:
  --key=value               Custom key-value pairs

Example with custom options:

./silly server.lua --port=8080 --workers=4 --env=production

Access in Lua:

local env = require "silly.env"
local port = env.get("port")        -- "8080"
local workers = env.get("workers")  -- "4"
local environment = env.get("env")  -- "production"

๐Ÿงช Testing

Run the complete test suite:

# Run all tests
make testall

# Run with address sanitizer (Linux/macOS)
make test

๐Ÿ“ฆ Dependencies

Silly has minimal dependencies:

  • Lua 5.4 (embedded)
  • jemalloc (optional, for better memory allocation)
  • OpenSSL (optional, for TLS support)
  • zlib (embedded, for compression)

All dependencies are automatically built via Git submodules.

๐Ÿค Contributing

We welcome contributions! Please see CONTRIBUTING.md for details.

Development Setup

# Clone with submodules
git clone --recursive https://github.com/findstr/silly.git

# Build in debug mode
make test

# Format code
make fmt

๐Ÿ“„ License

Silly is licensed under the MIT License.

๐Ÿ™ Acknowledgments

  • Lua - The elegant scripting language
  • jemalloc - Scalable concurrent memory allocator
  • OpenSSL - Robust cryptography toolkit

๐Ÿ“ฎ Contact & Community


About

Lightweight, high-performance Lua network framework. Supports TCP, UDP, WebSocket, gRPC, Redis, MySQL, Prometheus, and etcd v3. Includes SSL/TLS and a built-in debugger.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Languages