or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication-and-security.mdclassic-mode.mdcli-tools.mdconnection-factory.mdindex.mdregistry-and-discovery.mdservers.mdservices-protocols.mdstreams-and-channels.mdutilities.md

servers.mddocs/

0

# Server Implementations

1

2

Multi-threaded, forking, and specialized server implementations for hosting RPyC services. These servers provide different concurrency models and deployment options for various use cases, from development to high-performance production environments.

3

4

## Capabilities

5

6

### Base Server Class

7

8

Foundation server class providing common functionality for all server implementations.

9

10

```python { .api }

11

class Server:

12

"""

13

Base class for RPyC servers providing common server functionality.

14

"""

15

16

def __init__(self, service, hostname='0.0.0.0', port=0, backlog=10,

17

reuse_addr=True, authenticator=None, registrar=None, auto_register=None):

18

"""

19

Initialize server.

20

21

Parameters:

22

- service: Service class or instance to serve

23

- hostname (str): Host address to bind to

24

- port (int): Port to bind to (0 for automatic)

25

- backlog (int): Socket listen backlog

26

- reuse_addr (bool): Enable SO_REUSEADDR

27

- authenticator: Authentication handler

28

- registrar: Service registry client

29

- auto_register (bool): Auto-register with registry

30

"""

31

32

@property

33

def closed(self) -> bool:

34

"""True if server is closed"""

35

36

def start(self):

37

"""Start the server (blocks indefinitely)"""

38

39

def close(self):

40

"""Close the server and cleanup resources"""

41

42

def accept(self):

43

"""Accept a single client connection"""

44

45

def _authenticate_and_serve_client(self, sock):

46

"""Authenticate and serve single client"""

47

```

48

49

### Threaded Server

50

51

Multi-threaded server that creates a new thread for each client connection.

52

53

```python { .api }

54

class ThreadedServer(Server):

55

"""

56

Multi-threaded server creating new thread per client connection.

57

Good for moderate concurrency with I/O-bound services.

58

"""

59

60

def __init__(self, service, hostname='0.0.0.0', port=0, backlog=10,

61

reuse_addr=True, authenticator=None, registrar=None, auto_register=None):

62

"""

63

Initialize threaded server.

64

65

Parameters: Same as Server base class

66

"""

67

68

def _serve_client(self, sock, credentials):

69

"""Serve client in dedicated thread"""

70

```

71

72

### Thread Pool Server

73

74

Thread pool server that uses a fixed pool of worker threads to serve clients.

75

76

```python { .api }

77

class ThreadPoolServer(Server):

78

"""

79

Thread pool server using fixed number of worker threads.

80

Better resource management than ThreadedServer for high concurrency.

81

"""

82

83

def __init__(self, service, hostname='0.0.0.0', port=0, backlog=10,

84

reuse_addr=True, authenticator=None, registrar=None, auto_register=None,

85

nbthreads=10):

86

"""

87

Initialize thread pool server.

88

89

Parameters:

90

- nbthreads (int): Number of threads in pool

91

- Other parameters: Same as Server base class

92

"""

93

94

def _get_next_thread(self):

95

"""Get next available thread from pool"""

96

```

97

98

### Forking Server

99

100

Process-forking server that creates new process for each client connection (Unix only).

101

102

```python { .api }

103

class ForkingServer(Server):

104

"""

105

Forking server creating new process per client connection.

106

Provides process isolation but higher resource overhead (Unix only).

107

"""

108

109

def __init__(self, service, hostname='0.0.0.0', port=0, backlog=10,

110

reuse_addr=True, authenticator=None, registrar=None, auto_register=None):

111

"""

112

Initialize forking server.

113

114

Parameters: Same as Server base class

115

116

Note: Only available on Unix systems

117

"""

118

119

def _serve_client(self, sock, credentials):

120

"""Serve client in dedicated process"""

121

```

122

123

### One Shot Server

124

125

Single-connection server that handles one client and then terminates.

126

127

```python { .api }

128

class OneShotServer(Server):

129

"""

130

Single-connection server for one client only.

131

Useful for testing or simple point-to-point communication.

132

"""

133

134

def __init__(self, service, hostname='0.0.0.0', port=0, backlog=10,

135

reuse_addr=True, authenticator=None, registrar=None, auto_register=None):

136

"""

137

Initialize one-shot server.

138

139

Parameters: Same as Server base class

140

"""

141

142

def start(self):

143

"""Start server and handle single client connection"""

144

```

145

146

### Gevent Server

147

148

Gevent-based server using cooperative multitasking for high concurrency (requires gevent).

149

150

```python { .api }

151

class GeventServer(Server):

152

"""

153

Gevent-based server using cooperative multitasking.

154

Provides high concurrency with low resource overhead (requires gevent).

155

"""

156

157

def __init__(self, service, hostname='0.0.0.0', port=0, backlog=10,

158

reuse_addr=True, authenticator=None, registrar=None, auto_register=None):

159

"""

160

Initialize gevent server.

161

162

Parameters: Same as Server base class

163

164

Note: Requires gevent to be installed

165

"""

166

```

167

168

## Examples

169

170

### Basic Threaded Server

171

172

```python

173

import rpyc

174

from rpyc.utils.server import ThreadedServer

175

176

class MyService(rpyc.Service):

177

@rpyc.exposed

178

def get_data(self, key):

179

return f"Data for {key}"

180

181

# Create and start threaded server

182

server = ThreadedServer(MyService, port=12345)

183

print(f"Server listening on port {server.port}")

184

server.start() # Blocks indefinitely

185

```

186

187

### Thread Pool Server with Configuration

188

189

```python

190

import rpyc

191

from rpyc.utils.server import ThreadPoolServer

192

193

class ComputeService(rpyc.Service):

194

@rpyc.exposed

195

def heavy_computation(self, data):

196

# Simulate CPU-intensive work

197

import time

198

time.sleep(1)

199

return sum(data)

200

201

# Thread pool server with 20 worker threads

202

server = ThreadPoolServer(

203

ComputeService,

204

hostname='0.0.0.0',

205

port=12345,

206

nbthreads=20

207

)

208

209

print(f"Compute server with 20 threads on port {server.port}")

210

server.start()

211

```

212

213

### Forking Server with Authentication

214

215

```python

216

import rpyc

217

from rpyc.utils.server import ForkingServer

218

from rpyc.utils.authenticators import SSLAuthenticator

219

220

class SecureService(rpyc.Service):

221

@rpyc.exposed

222

def sensitive_operation(self):

223

return "Secret data"

224

225

# SSL authenticator

226

auth = SSLAuthenticator('server.key', 'server.crt')

227

228

# Forking server with SSL auth

229

server = ForkingServer(

230

SecureService,

231

port=12345,

232

authenticator=auth

233

)

234

235

print("Secure forking server started")

236

server.start()

237

```

238

239

### One Shot Server for Testing

240

241

```python

242

import rpyc

243

from rpyc.utils.server import OneShotServer

244

245

class TestService(rpyc.Service):

246

@rpyc.exposed

247

def test_function(self):

248

return "Test successful"

249

250

# One-shot server for single test connection

251

server = OneShotServer(TestService, port=0) # Auto-assign port

252

print(f"Test server on port {server.port}")

253

254

# In testing scenario, this would handle one connection and exit

255

server.start()

256

```

257

258

### Server with Service Registry

259

260

```python

261

import rpyc

262

from rpyc.utils.server import ThreadedServer

263

from rpyc.utils.registry import UDPRegistryClient

264

265

class CalculatorService(rpyc.Service):

266

SERVICE_NAME = "CALCULATOR"

267

268

@rpyc.exposed

269

def add(self, a, b):

270

return a + b

271

272

@rpyc.exposed

273

def multiply(self, a, b):

274

return a * b

275

276

# Connect to registry

277

registry = UDPRegistryClient()

278

279

# Server with auto-registration

280

server = ThreadedServer(

281

CalculatorService,

282

port=12345,

283

registrar=registry,

284

auto_register=True

285

)

286

287

print("Calculator service registered and running")

288

server.start()

289

```

290

291

### Gevent Server for High Concurrency

292

293

```python

294

import rpyc

295

from rpyc.utils.server import GeventServer

296

297

class HighConcurrencyService(rpyc.Service):

298

@rpyc.exposed

299

def io_operation(self, data):

300

# Simulate I/O-bound work

301

import gevent

302

gevent.sleep(0.1)

303

return f"Processed: {data}"

304

305

# Gevent server handles thousands of concurrent connections

306

server = GeventServer(HighConcurrencyService, port=12345)

307

print("High concurrency gevent server started")

308

server.start()

309

```

310

311

### Server Context Manager

312

313

```python

314

import rpyc

315

from rpyc.utils.server import ThreadedServer

316

317

class MyService(rpyc.Service):

318

@rpyc.exposed

319

def get_status(self):

320

return "Running"

321

322

# Use server as context manager

323

with ThreadedServer(MyService, port=12345) as server:

324

print(f"Server running on port {server.port}")

325

# Server automatically closes when leaving context

326

327

# Could run for specific time or until condition

328

import time

329

time.sleep(10) # Run for 10 seconds

330

```

331

332

### Custom Server Subclass

333

334

```python

335

import rpyc

336

from rpyc.utils.server import ThreadedServer

337

import logging

338

339

class LoggingServer(ThreadedServer):

340

"""Custom server with detailed logging"""

341

342

def _authenticate_and_serve_client(self, sock):

343

client_addr = sock.getpeername()

344

logging.info(f"Client connecting from {client_addr}")

345

346

try:

347

super()._authenticate_and_serve_client(sock)

348

logging.info(f"Client {client_addr} disconnected normally")

349

except Exception as e:

350

logging.error(f"Client {client_addr} error: {e}")

351

352

class MyService(rpyc.Service):

353

@rpyc.exposed

354

def hello(self):

355

return "Hello from logged server"

356

357

# Setup logging

358

logging.basicConfig(level=logging.INFO)

359

360

# Use custom server

361

server = LoggingServer(MyService, port=12345)

362

server.start()

363

```

364

365

### Server Configuration Options

366

367

```python

368

import rpyc

369

from rpyc.utils.server import ThreadedServer

370

371

class ConfiguredService(rpyc.Service):

372

@rpyc.exposed

373

def get_config(self):

374

return "Service running with custom config"

375

376

# Server with various configuration options

377

server = ThreadedServer(

378

ConfiguredService,

379

hostname='127.0.0.1', # Bind to localhost only

380

port=12345, # Specific port

381

backlog=50, # Large connection queue

382

reuse_addr=True # Allow address reuse

383

)

384

385

# Configure the service's protocol

386

server.protocol_config = {

387

'sync_request_timeout': 60, # 60 second request timeout

388

'allow_pickle': False, # Disable pickle for security

389

'allow_all_attrs': False # Restrict attribute access

390

}

391

392

server.start()

393

```