0
# Multi-Instance Management
1
2
Thread-safe management of multiple milvus-lite server instances with automatic lifecycle handling and resource cleanup. The ServerManager provides a high-level interface for managing multiple independent databases in multi-tenant or multi-database scenarios.
3
4
## Capabilities
5
6
### ServerManager Class
7
8
Centralized manager for multiple server instances with thread-safe operations and automatic resource management.
9
10
```python { .api }
11
class ServerManager:
12
"""
13
Thread-safe manager for multiple milvus-lite server instances.
14
15
Manages server lifecycle, prevents resource conflicts, and provides
16
automatic cleanup for all managed servers.
17
"""
18
19
def __init__(self):
20
"""Initialize server manager with thread lock and server registry."""
21
22
def start_and_get_uri(self, path: str, args=None) -> Optional[str]:
23
"""
24
Start server for given database path and return connection URI.
25
26
Creates or reuses existing server instance for the specified path.
27
Thread-safe operation with automatic server lifecycle management.
28
29
Parameters:
30
- path (str): Path to database file
31
- args: Additional server arguments (currently unused)
32
33
Returns:
34
- Optional[str]: Connection URI on success, None on failure
35
"""
36
37
def release_server(self, path: str) -> None:
38
"""
39
Stop and remove server for given database path.
40
41
Thread-safe operation that stops the server process, cleans up
42
resources, and removes it from the managed server registry.
43
44
Parameters:
45
- path (str): Path to database file
46
"""
47
48
def release_all(self) -> None:
49
"""
50
Stop and remove all managed servers.
51
52
Thread-safe bulk operation for cleanup of all server instances.
53
Useful for application shutdown or resource cleanup.
54
"""
55
56
def __del__(self) -> None:
57
"""Destructor that releases all servers when manager is destroyed."""
58
```
59
60
**Usage Example:**
61
62
```python
63
from milvus_lite.server_manager import server_manager_instance
64
65
# Start server and get connection URI
66
uri = server_manager_instance.start_and_get_uri("./database1.db")
67
if uri:
68
print(f"Database1 available at: {uri}")
69
70
# Use URI with pymilvus client
71
from pymilvus import MilvusClient
72
client = MilvusClient(uri=uri)
73
client.create_collection("test", dimension=128)
74
75
# Start additional servers for different databases
76
uri2 = server_manager_instance.start_and_get_uri("./database2.db")
77
uri3 = server_manager_instance.start_and_get_uri("/tmp/temp_vectors.db")
78
79
# Release specific server when done
80
server_manager_instance.release_server("./database1.db")
81
82
# Cleanup all servers (usually at application shutdown)
83
server_manager_instance.release_all()
84
```
85
86
### Global Server Manager Instance
87
88
Pre-configured singleton instance for convenient server management across the application.
89
90
```python { .api }
91
server_manager_instance: ServerManager
92
```
93
94
This global instance is automatically created when importing the module and provides a convenient way to manage servers without manual instantiation.
95
96
**Usage Example:**
97
98
```python
99
from milvus_lite.server_manager import server_manager_instance
100
101
# Use global instance directly
102
uri = server_manager_instance.start_and_get_uri("./app_database.db")
103
104
# The instance is shared across all imports
105
# Multiple modules can use the same server_manager_instance
106
```
107
108
### Multi-Database Operations
109
110
Manage multiple independent databases simultaneously with isolated server instances.
111
112
**Usage Example:**
113
114
```python
115
from milvus_lite.server_manager import server_manager_instance
116
from pymilvus import MilvusClient
117
118
class MultiDatabaseApp:
119
def __init__(self):
120
self.databases = {}
121
122
def add_database(self, name: str, db_path: str):
123
"""Add a new database to the application."""
124
uri = server_manager_instance.start_and_get_uri(db_path)
125
if uri:
126
client = MilvusClient(uri=uri)
127
self.databases[name] = {
128
'uri': uri,
129
'path': db_path,
130
'client': client
131
}
132
print(f"Database '{name}' added successfully")
133
return True
134
return False
135
136
def remove_database(self, name: str):
137
"""Remove database from application."""
138
if name in self.databases:
139
db_path = self.databases[name]['path']
140
server_manager_instance.release_server(db_path)
141
del self.databases[name]
142
print(f"Database '{name}' removed")
143
144
def list_databases(self):
145
"""List all active databases."""
146
return list(self.databases.keys())
147
148
def get_client(self, name: str) -> Optional[MilvusClient]:
149
"""Get client for specific database."""
150
return self.databases.get(name, {}).get('client')
151
152
def shutdown(self):
153
"""Cleanup all databases."""
154
server_manager_instance.release_all()
155
self.databases.clear()
156
157
# Usage
158
app = MultiDatabaseApp()
159
app.add_database("users", "./users.db")
160
app.add_database("products", "./products.db")
161
app.add_database("analytics", "./analytics.db")
162
163
# Use different databases
164
user_client = app.get_client("users")
165
if user_client:
166
user_client.create_collection("profiles", dimension=256)
167
168
product_client = app.get_client("products")
169
if product_client:
170
product_client.create_collection("embeddings", dimension=512)
171
172
# Cleanup when done
173
app.shutdown()
174
```
175
176
### Thread Safety
177
178
All ServerManager operations are thread-safe and can be used safely in multi-threaded applications.
179
180
**Usage Example:**
181
182
```python
183
import threading
184
from milvus_lite.server_manager import server_manager_instance
185
186
def worker_thread(thread_id: int):
187
"""Worker function for multi-threaded database access."""
188
db_path = f"./worker_{thread_id}.db"
189
190
# Thread-safe server startup
191
uri = server_manager_instance.start_and_get_uri(db_path)
192
if uri:
193
# Each thread gets its own database instance
194
from pymilvus import MilvusClient
195
client = MilvusClient(uri=uri)
196
197
# Perform thread-specific operations
198
collection_name = f"thread_{thread_id}_data"
199
client.create_collection(collection_name, dimension=128)
200
201
# Insert some data specific to this thread
202
data = [{"id": i, "vector": [0.1 * thread_id] * 128}
203
for i in range(10)]
204
client.insert(collection_name, data)
205
206
print(f"Thread {thread_id} completed operations")
207
208
# Server cleanup is handled automatically by manager
209
210
# Start multiple worker threads
211
threads = []
212
for i in range(5):
213
thread = threading.Thread(target=worker_thread, args=(i,))
214
threads.append(thread)
215
thread.start()
216
217
# Wait for all threads to complete
218
for thread in threads:
219
thread.join()
220
221
# Cleanup all servers created by threads
222
server_manager_instance.release_all()
223
```
224
225
## Resource Management
226
227
The ServerManager automatically handles resource management including process cleanup, file locks, and memory management.
228
229
**Automatic Cleanup:**
230
- Server processes are terminated when no longer needed
231
- File locks are released properly
232
- Temporary files (sockets, locks) are cleaned up
233
- Memory is freed when servers are removed from registry
234
235
**Resource Limits:**
236
- Each database file can only be managed by one server instance
237
- File locking prevents multiple processes from accessing same database
238
- Thread locks prevent concurrent modification of server registry
239
- Automatic cleanup on manager destruction
240
241
**Best Practices:**
242
- Use `release_server()` when done with specific databases
243
- Call `release_all()` during application shutdown
244
- Monitor memory usage when managing many concurrent databases
245
- Use path normalization for consistent database identification
246
247
**Path Handling:**
248
- All paths are automatically resolved to absolute paths
249
- Path normalization ensures consistent server identification
250
- Symbolic links are resolved to prevent duplicate servers
251
- Invalid paths result in server startup failure