Skip to content

Commit 85114fd

Browse files
committed
readme.md
1 parent f864aa3 commit 85114fd

1 file changed

Lines changed: 210 additions & 0 deletions

File tree

README.md

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
# Connection - Base Class for TCP Connections
2+
3+
A Lua module providing a foundation for managing TCP socket connections in Tarantool applications. This library offers an object-oriented approach to handling network connections with support for asynchronous operations, automatic reconnection, and customizable event handling.
4+
5+
## Features
6+
7+
- Asynchronous TCP connection management
8+
- Automatic reconnection with configurable timeout
9+
- Buffer management for both reading and writing
10+
- Event-based architecture with callbacks
11+
- Non-blocking I/O
12+
13+
## Installation
14+
15+
### Using Tarantool Rocks
16+
17+
```bash
18+
tt rocks --server https://moonlibs.org install connection
19+
```
20+
21+
### Manual Installation
22+
23+
Clone the repository and install using the rockspec:
24+
25+
```bash
26+
git clone https://github.com/moonlibs/connection
27+
cd connection
28+
tt rocks make
29+
```
30+
31+
## Usage
32+
33+
### Basic Connection
34+
35+
```lua
36+
local connection = require('connection')
37+
38+
-- Create a new connection
39+
local conn = connection.new('example.com', 8080)
40+
41+
-- Wait for connection to be established (if needed)
42+
conn.connwait:get(timeout)
43+
44+
-- Send data
45+
conn:push_write("Hello, server!")
46+
conn:flush()
47+
48+
-- Close connection when done
49+
conn:close()
50+
```
51+
52+
### Connection Options
53+
54+
```lua
55+
local default_options = {
56+
timeout = 1/3, -- Connection and request timeout in seconds
57+
autoconnect = true, -- Connect immediately when created
58+
reconnect = 1/3, -- Reconnect after 1/3 seconds if connection fails
59+
maxbuf = 2 * 1024 * 1024 -- 2MB read buffer size for read
60+
}
61+
62+
local conn = connection.new('example.com', 8080, {
63+
timeout = 1, -- Connection and request timeout in seconds
64+
autoconnect = true, -- Connect immediately when created
65+
reconnect = 0.5, -- Reconnect after 0.5 seconds if connection fails
66+
maxbuf = 2 * 1024 * 1024 -- 2MB read buffer size for read
67+
})
68+
```
69+
70+
### Custom Event Handlers
71+
72+
```lua
73+
local obj = require('obj')
74+
local connection = require('connection')
75+
76+
local MyConnection = obj.class({}, 'MyConnection', connection)
77+
78+
function MyConnection:on_connected()
79+
self:log('I', 'Successfully connected!')
80+
-- Initialize session, authenticate, etc.
81+
end
82+
83+
function MyConnection:on_disconnect(err)
84+
self:log('W', 'Disconnected: %s', err)
85+
-- Clean up resources
86+
end
87+
88+
function MyConnection:on_read(is_last)
89+
-- Process received data
90+
local data = ffi.string(self.rbuf, self.avail)
91+
self:log('D', 'Received data: %s', data)
92+
93+
-- Important: reset buffer position after processing
94+
self.avail = 0
95+
end
96+
97+
-- Create instance of your connection
98+
local conn = MyConnection:new('example.com', 8080)
99+
```
100+
101+
## Connection States
102+
103+
The connection can be in one of the following states:
104+
105+
- `NOTCONNECTED` (0) - Initial state, not connected
106+
- `CONNECTING` (1) - Connection attempt in progress
107+
- `CONNECTED` (2) - Successfully connected
108+
- `RECONNECTING` (3) - Attempting to reconnect after failure
109+
110+
You can check the current state:
111+
112+
```lua
113+
if conn.state == connection.S2S.CONNECTED then
114+
-- Connection is established
115+
end
116+
```
117+
118+
## API Reference
119+
120+
### Methods (all methods never yields)
121+
122+
- `new(host, port, options)` - Create a new connection
123+
- `connect()` - Initiate connection
124+
- `push_write(buf, len)` - Queue data to be sent, reallocates write buffer
125+
- `flush()` - Send queued data
126+
- `close()` - Close the connection, connection can be reused
127+
- `destroy()` - Clean up resources, makes connection unusable
128+
- `fdno()` - Returns file descriptor (or -1)
129+
130+
### Callbacks (executed in separate fiber)
131+
132+
- `on_connected()` - Called when connection is established, executed in separate fiber
133+
- `on_disconnect(err: string)` - Called when connection is closed, executed in separate fiber
134+
- `on_connect_failed(errno_code)` - Called when connection attempt fails, reconnection logic is performed here
135+
- `on_connect_reset(errno_code)` - Called when connection is reset (closed due to an error)
136+
137+
### Reading data
138+
139+
- `on_read(is_last)` - Called when data is available for reading, from rw (read worker) fiber.
140+
- **Important**: `on_read` is called directly from the read worker fiber. If your callback yields (using `fiber.sleep()` or other yielding operations), reading from the socket is stopped until the callback returns.
141+
- If an exception is raised inside `on_read`, the connection will be reset. The connection can be reestablished automatically if the `reconnect` option is set.
142+
143+
### Protected methods
144+
145+
- `_cleanup(errno_code)` - Executes cleanup of all resources, closes socket, cancels fibers, drains buffers
146+
147+
## Example: Echo Client
148+
149+
Here's a simple echo client implementation that demonstrates basic usage:
150+
151+
```lua
152+
local connection = require('connection')
153+
local fiber = require('fiber')
154+
local ffi = require('ffi')
155+
local obj = require('obj')
156+
157+
local EchoClient = obj.class({}, 'EchoClient', connection)
158+
159+
function EchoClient:on_connected()
160+
self:log('I', 'Connected to echo server')
161+
-- Send a message when connected
162+
self:push_write("Hello, Echo Server!\n")
163+
self:flush()
164+
end
165+
166+
function EchoClient:on_read(is_last)
167+
-- Process the received echo response
168+
local data = ffi.string(self.rbuf, self.avail)
169+
self:log('I', 'Received echo: %s', data)
170+
171+
-- Clear the buffer after processing
172+
self.avail = 0
173+
174+
-- Send another message
175+
if not is_last then
176+
-- yielding in on_read callback stops read from socket.
177+
fiber.sleep(1)
178+
self:push_write("Another message!\n")
179+
self:flush()
180+
end
181+
end
182+
183+
function EchoClient:on_disconnect(err)
184+
self:log('W', 'Disconnected from echo server: %s', err)
185+
end
186+
187+
-- Usage example
188+
local function test_echo_client()
189+
local client = EchoClient:new('localhost', 7777)
190+
client.connwait:get(2) -- Wait up to 2 seconds for connection
191+
192+
-- Keep the client running for a while
193+
fiber.sleep(5)
194+
195+
-- Close the connection
196+
client:close()
197+
end
198+
199+
fiber.create(test_echo_client)
200+
```
201+
202+
## Real-World Examples
203+
204+
Some real world examples
205+
206+
[connection-legacy](https://github.com/moonlibs/connection-legacy) repository, which implements a backward compatible API on top of this module.
207+
208+
[connection-scribe](https://github.com/moonlibs/connection-scribe) repository, which implements Scribe protocol
209+
210+
[tarantool1.5-replica](https://github.com/ochaton/migrate/blob/master/migrate/replica.lua) repository, which implements replication protocol of Tarantool 1.5

0 commit comments

Comments
 (0)