0
# Node Management
1
2
Comprehensive connection and management of Lavalink servers including pool management, node discovery, health monitoring, and load balancing across multiple nodes. The node system provides the foundation for all wavelink functionality by managing connections to Lavalink servers.
3
4
## Capabilities
5
6
### Pool Management
7
8
The Pool class provides global management of Lavalink nodes with automatic load balancing, connection pooling, and node selection for optimal performance.
9
10
```python { .api }
11
class Pool:
12
@classmethod
13
async def connect(
14
cls,
15
uri: str,
16
password: str,
17
*,
18
identifier: str | None = None,
19
client: discord.Client,
20
**kwargs
21
) -> Node:
22
"""
23
Connect to a Lavalink node and add it to the pool.
24
25
Parameters:
26
- uri: The URI of the Lavalink server (e.g., "http://localhost:2333")
27
- password: Authentication password for the Lavalink server
28
- identifier: Optional unique identifier for the node
29
- client: The discord.py client instance
30
- **kwargs: Additional connection parameters
31
32
Returns:
33
Node: The connected Node instance
34
35
Raises:
36
InvalidClientException: If the client is invalid
37
AuthorizationFailedException: If authentication fails
38
"""
39
40
@classmethod
41
async def reconnect(cls) -> dict[str, Node]:
42
"""
43
Reconnect all nodes in the pool.
44
45
Returns:
46
dict[str, Node]: Dictionary of reconnected nodes by identifier
47
"""
48
49
@classmethod
50
async def close(cls) -> None:
51
"""Close all node connections in the pool."""
52
53
@classmethod
54
def get_node(cls, identifier: str | None = None) -> Node:
55
"""
56
Get a node from the pool by identifier.
57
58
Parameters:
59
- identifier: Node identifier, if None returns best available node
60
61
Returns:
62
Node: The requested node
63
64
Raises:
65
InvalidNodeException: If node doesn't exist or pool is empty
66
"""
67
68
@classmethod
69
async def fetch_tracks(
70
cls,
71
query: str,
72
*,
73
node: Node | None = None
74
) -> list[Playable] | Playlist:
75
"""
76
Search for tracks using the pool's nodes.
77
78
Parameters:
79
- query: Search query (URL, search terms, etc.)
80
- node: Specific node to use, if None uses best available
81
82
Returns:
83
list[Playable] | Playlist: Search results
84
85
Raises:
86
LavalinkLoadException: If track loading fails
87
"""
88
89
@classmethod
90
def cache(cls, capacity: int | None | bool = None) -> None:
91
"""
92
Configure track caching for the pool.
93
94
Parameters:
95
- capacity: Cache capacity (None for unlimited, False to disable)
96
"""
97
98
@classmethod
99
def has_cache(cls) -> bool:
100
"""
101
Check if track caching is enabled.
102
103
Returns:
104
bool: True if caching is enabled
105
"""
106
107
@classmethod
108
@property
109
def nodes(cls) -> dict[str, Node]:
110
"""
111
All connected nodes in the pool.
112
113
Returns:
114
dict[str, Node]: Dictionary of nodes by identifier
115
"""
116
```
117
118
### Node Connection
119
120
Individual Lavalink server connection management with REST API access, WebSocket communication, and comprehensive server interaction.
121
122
```python { .api }
123
class Node:
124
def __init__(
125
self,
126
*,
127
uri: str,
128
password: str,
129
identifier: str | None = None,
130
client: discord.Client | None = None,
131
**kwargs
132
):
133
"""
134
Initialize a new Node connection.
135
136
Parameters:
137
- uri: Lavalink server URI
138
- password: Authentication password
139
- identifier: Unique node identifier
140
- client: Discord client instance
141
"""
142
143
@property
144
def headers(self) -> dict[str, str]:
145
"""HTTP headers used for REST requests."""
146
147
@property
148
def identifier(self) -> str:
149
"""Unique identifier for this node."""
150
151
@property
152
def uri(self) -> str:
153
"""URI of the Lavalink server."""
154
155
@property
156
def status(self) -> NodeStatus:
157
"""Current connection status of the node."""
158
159
@property
160
def players(self) -> dict[int, Player]:
161
"""Dictionary of active players on this node by guild ID."""
162
163
@property
164
def client(self) -> discord.Client | None:
165
"""Connected Discord client instance."""
166
167
@property
168
def password(self) -> str:
169
"""Authentication password for the node."""
170
171
@property
172
def heartbeat(self) -> float:
173
"""WebSocket heartbeat interval."""
174
175
@property
176
def session_id(self) -> str | None:
177
"""Current WebSocket session ID."""
178
179
async def close(self, *, eject: bool = False) -> None:
180
"""
181
Close the node connection.
182
183
Parameters:
184
- eject: Whether to eject players before closing
185
"""
186
187
async def send(self, **data) -> None:
188
"""
189
Send data to the node via WebSocket.
190
191
Parameters:
192
- **data: Data to send to the node
193
"""
194
195
async def fetch_players(self) -> list[PlayerResponsePayload]:
196
"""
197
Fetch information about all players on this node.
198
199
Returns:
200
list[PlayerResponsePayload]: List of player information
201
"""
202
203
async def fetch_player_info(self, guild_id: int) -> PlayerResponsePayload | None:
204
"""
205
Fetch information about a specific player.
206
207
Parameters:
208
- guild_id: Discord guild ID
209
210
Returns:
211
PlayerResponsePayload | None: Player information or None if not found
212
"""
213
214
async def fetch_info(self) -> InfoResponsePayload:
215
"""
216
Fetch node and Lavalink server information.
217
218
Returns:
219
InfoResponsePayload: Node information including version, plugins, etc.
220
"""
221
222
async def fetch_stats(self) -> StatsResponsePayload:
223
"""
224
Fetch node performance statistics.
225
226
Returns:
227
StatsResponsePayload: Node statistics including CPU, memory, etc.
228
"""
229
230
async def fetch_version(self) -> str:
231
"""
232
Fetch the Lavalink server version.
233
234
Returns:
235
str: Server version string
236
"""
237
238
def get_player(self, guild_id: int) -> Player | None:
239
"""
240
Get a player by guild ID.
241
242
Parameters:
243
- guild_id: Discord guild ID
244
245
Returns:
246
Player | None: Player instance or None if not found
247
"""
248
```
249
250
### Node Status
251
252
Enumeration of possible node connection states for monitoring and health checking.
253
254
```python { .api }
255
class NodeStatus(enum.Enum):
256
"""
257
Enum representing the connection status of a Node.
258
"""
259
DISCONNECTED = 0 # Never connected or disconnected
260
CONNECTING = 1 # Currently attempting connection
261
CONNECTED = 2 # Successfully connected
262
```
263
264
## Usage Examples
265
266
### Basic Node Connection
267
268
```python
269
import wavelink
270
import discord
271
272
# Connect to a single Lavalink node
273
bot = commands.Bot(command_prefix='!', intents=discord.Intents.all())
274
275
@bot.event
276
async def on_ready():
277
# Connect to local Lavalink server
278
node = await wavelink.Pool.connect(
279
uri="http://localhost:2333",
280
password="youshallnotpass",
281
client=bot,
282
identifier="main_node"
283
)
284
print(f"Connected to node: {node.identifier}")
285
```
286
287
### Multiple Node Setup
288
289
```python
290
@bot.event
291
async def on_ready():
292
# Connect to multiple nodes for redundancy
293
nodes = [
294
("http://localhost:2333", "password1", "node1"),
295
("http://lavalink2.example.com:2333", "password2", "node2"),
296
]
297
298
for uri, password, identifier in nodes:
299
try:
300
await wavelink.Pool.connect(
301
uri=uri,
302
password=password,
303
client=bot,
304
identifier=identifier
305
)
306
print(f"Connected to {identifier}")
307
except wavelink.AuthorizationFailedException:
308
print(f"Failed to authenticate with {identifier}")
309
```
310
311
### Node Health Monitoring
312
313
```python
314
async def check_node_health():
315
"""Check the health of all connected nodes."""
316
for identifier, node in wavelink.Pool.nodes.items():
317
if node.status == wavelink.NodeStatus.CONNECTED:
318
try:
319
stats = await node.fetch_stats()
320
print(f"Node {identifier}: CPU {stats['cpu']['used']}%, Memory {stats['memory']['used']}MB")
321
except Exception as e:
322
print(f"Failed to get stats for {identifier}: {e}")
323
else:
324
print(f"Node {identifier} is {node.status.name}")
325
```
326
327
### Caching Configuration
328
329
```python
330
# Enable track caching with 1000 track capacity
331
wavelink.Pool.cache(capacity=1000)
332
333
# Check if caching is enabled
334
if wavelink.Pool.has_cache():
335
print("Track caching is enabled")
336
337
# Disable caching
338
wavelink.Pool.cache(capacity=False)
339
```