Getting Started
Getting Started
Welcome to the Silly framework! This tutorial will guide you from scratch to install, configure, and run your first high-performance network application in 10 minutes.
Introduction
What is Silly?
Silly is a lightweight, high-performance server framework designed for building high-concurrency network applications. It combines:
- C Performance: Core components written in C for exceptional performance
- Lua Flexibility: Business logic implemented in Lua for efficient development
- Coroutine-Driven: Uses Lua coroutines to implement a clean asynchronous programming model
What is it Good For?
Silly is particularly suitable for building the following types of applications:
- Game Servers: High-concurrency, low-latency game backends
- API Services: RESTful APIs, gRPC services
- Real-time Communication: WebSocket services, instant messaging
- Network Proxies: TCP/UDP proxies, load balancers
Performance
Test results on Intel i7-10700 @ 2.90GHz:
- Throughput: 200,000+ requests/second
- Latency: P99 < 1ms
- Concurrency: Supports 65,535 concurrent connections
System Requirements
Operating Systems
Silly supports the following operating systems:
- Linux: Recommended for production environments (uses epoll)
- macOS: Suitable for development environments (uses kqueue)
- Windows: Supports MinGW compilation (uses IOCP)
Dependencies
Required Dependencies
- GCC or Clang: C compiler
- Make: Build tool
- Git: For cloning code and submodules
Optional Dependencies
- OpenSSL: Enable TLS/SSL support (recommended)
- jemalloc: Better memory allocation performance (enabled by default)
Installing Dependencies
sudo apt-get update
sudo apt-get install -y build-essential git libssl-devsudo yum groupinstall "Development Tools"
sudo yum install -y git openssl-devel# Install Xcode Command Line Tools
xcode-select --install
# Install OpenSSL (optional)
brew install opensslInstallation Steps
1. Clone the Repository
# Clone repository (including submodules)
git clone --recursive https://github.com/findstr/silly.git
cd sillyNote
If you forgot to use --recursive, you can initialize submodules with:
git submodule update --init --recursive2. Compile the Framework
# Standard compilation
makeAdvanced Compilation Options
# Disable OpenSSL support (enabled by default)
make OPENSSL=off
# Use glibc memory allocator (for debugging)
make MALLOC=glibc
# Compile test version (with address sanitizer)
make test
# Clean build artifacts
make clean3. Verify Installation
# Check executable
./silly --versionYou should see the version number:
0.6Congratulations! Silly has been successfully installed.
Your First Program
Let's create a simple "Hello World" program to experience Silly.
Create hello.lua
Create a file named hello.lua in the silly directory:
-- Import silly core module
local silly = require "silly"
print("Hello, Silly!")
print("Current process ID:", silly.pid)
print("Framework version:", silly.version)
-- Exit program
silly.exit(0)Run the Program
./silly hello.luaUnderstanding the Output
You will see:
Hello, Silly!
Current process ID: 12345
Framework version: 0.6What Happened?
require "silly"gets the silly framework interfaceprint()outputs information to the consolesilly.exit(0)gracefully exits the process
Core Concepts
Before diving deeper, it's important to understand several core concepts of Silly.
1. Coroutine Model
Silly uses Lua coroutines to implement asynchronous programming, making async code look as clean as synchronous code.
Traditional Callback Style (complex, hard to maintain):
-- Callback hell example (Silly doesn't require this style)
socket.connect(addr, function(fd)
socket.read(fd, function(data1)
socket.write(fd, data1, function()
socket.read(fd, function(data2)
socket.write(fd, data2, function()
socket.close(fd)
end)
end)
end)
end)
end)Silly Coroutine Style (clear, readable):
-- Silly's coroutine approach
local tcp = require "silly.net.tcp"
local task = require "silly.task"
task.fork(function()
local conn = tcp.connect("127.0.0.1:8080")
local data1 = conn:read(1024)
conn:write(data1)
local data2 = conn:read(1024)
conn:write(data2)
conn:close()
end)2. Event Loop
Silly uses a single-threaded event loop to handle all business logic:
┌─────────────────────────────┐
│ Wait for events │
│ (socket/timer) │
└──────────┬──────────────────┘
│
▼
┌─────────────────────────────┐
│ Dispatch events to │
│ coroutine handlers │
└──────────┬──────────────────┘
│
▼
┌─────────────────────────────┐
│ Execute coroutine until │
│ suspended │
└──────────┬──────────────────┘
│
└────► LoopWhy Single-Threaded?
The single-threaded model avoids complex multi-threading issues like locks and race conditions, while achieving high concurrency through asynchronous I/O and coroutines. This is the proven pattern used by high-performance systems like Node.js and Nginx.
3. task.fork() - Creating Concurrent Tasks
task.fork() is used to create new coroutine tasks for concurrent processing:
local silly = require "silly"
local task = require "silly.task"
local time = require "silly.time"
print("Main task started")
-- Create two concurrent tasks
task.fork(function()
time.sleep(1000) -- Sleep for 1 second
print("Task 1 completed")
end)
task.fork(function()
time.sleep(500) -- Sleep for 0.5 seconds
print("Task 2 completed")
end)
print("Main task continues")Output Order:
Main task started
Main task continues
Task 2 completed # After 0.5 seconds
Task 1 completed # After 1 second4. A Complete Example
Let's create a simple timer program to consolidate what we've learned:
Create timer_demo.lua:
local silly = require "silly"
local task = require "silly.task"
local time = require "silly.time"
print("Timer demo started")
-- Task 1: Print every second
task.fork(function()
for i = 1, 5 do
print(string.format("[Task1] Second %d", i))
time.sleep(1000)
end
end)
-- Task 2: Print every 0.5 seconds
task.fork(function()
for i = 1, 10 do
print(string.format(" [Task2] Iteration %d (%.1fs)", i, i * 0.5))
time.sleep(500)
end
end)
-- Main task: Exit after 6 seconds
task.fork(function()
time.sleep(6000)
print("Demo ended")
silly.exit(0)
end)Run:
./silly timer_demo.luaYou will see two tasks executing alternately until the program exits.
Next Steps
Congratulations on completing the Getting Started tutorial! Now you have:
- Successfully installed and run Silly
- Understood the basic concepts of coroutines and event loops
- Learned to use
task.fork()to create concurrent tasks - Created your first timer program
Recommended Learning Path
- Echo Server Tutorial - Learn how to build a high-performance TCP server (implemented in 10 lines of code)
- Core Concepts - Deeply understand coroutines, message queues, schedulers, and other core mechanisms
- Guides - Learn how to solve specific problems in actual development
- API Reference - Consult complete API documentation
More Examples
Continue learning with these tutorials to master more features:
- HTTP Server - Build RESTful API services
- WebSocket Chat - Implement real-time communication applications
- Database Application - Use MySQL to store data
Troubleshooting
Common Issues
1. Compilation Failed: lua.h Not Found
Problem:
fatal error: lua.h: No such file or directorySolution:
# Ensure submodules are initialized
git submodule update --init --recursive2. Runtime: Lua Library Not Found
Problem:
module 'silly' not foundSolution:
# Run with correct path
./silly your_script.lua
# Or specify Lua library path
./silly your_script.lua --lualib_path="lualib/?.lua"3. Port Already in Use
Problem:
bind failed: Address already in useSolution:
# Find process using the port
lsof -i :8080
# Or use a different port
# Use a different port number in code, e.g., 80814. Permission Denied
Problem:
Permission deniedSolution:
# Add execute permission to the executable
chmod +x silly
# Or run as administrator (not recommended)
sudo ./silly your_script.luaGetting Help
If you encounter other problems:
- Check GitHub Issues
- Read Wiki Documentation
- Refer to tutorials and guides in the documentation
Debugging Tips
Enable Debug Logging
./silly your_script.lua --loglevel=debugView Command Line Help
./silly --helpOutput includes all available options:
Usage: silly main.lua [options]
Options:
-h, --help help
-v, --version version
-d, --daemon run as a daemon
-p, --logpath PATH path for the log file
-l, --loglevel LEVEL logging level (e.g. debug, info, warn, error)
-f, --pidfile FILE path for the PID file
-L, --lualib_path PATH path for Lua libraries
-C, --lualib_cpath PATH path for C Lua libraries
-S, --socket_cpu_affinity affinity for socket thread
-W, --worker_cpu_affinity affinity for worker threads
-T, --timer_cpu_affinity affinity for timer threadSummary
This tutorial covered:
- Installation: Cloning code, compiling, verification
- First Program: Hello World example
- Core Concepts: Coroutines, event loop, concurrent tasks
- Practical Example: Timer program
- Troubleshooting: Common problem solutions
Now you have mastered the basics of Silly and can start building real network applications! Continue reading the Echo Server Tutorial to learn how to implement a high-performance server that handles 200,000 requests per second with just 10 lines of code.