or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

events.mdindex.mdruntime.mdscheduling.mdscopes.mdserver.mdshutdown.md

server.mddocs/

0

# Server Lifecycle

1

2

Embedded server abstraction and lifecycle management for web applications. Provides unified interface for different server implementations with comprehensive startup/shutdown coordination and server information access.

3

4

## Capabilities

5

6

### EmbeddedServer Interface

7

8

Core interface for embedded server implementations providing server metadata and lifecycle management.

9

10

```java { .api }

11

/**

12

* Interface for embedded server implementations

13

* Extends EmbeddedApplication with server-specific functionality

14

*/

15

public interface EmbeddedServer extends EmbeddedApplication<EmbeddedServer> {

16

17

/**

18

* Get the port the server is listening on

19

* @return Server port number

20

*/

21

int getPort();

22

23

/**

24

* Get the host the server is bound to

25

* @return Server host address

26

*/

27

String getHost();

28

29

/**

30

* Get the URL scheme (protocol) used by the server

31

* @return URL scheme (typically "http" or "https")

32

*/

33

String getScheme();

34

35

/**

36

* Get the complete server URL

37

* @return Full server URL including scheme, host, and port

38

*/

39

URL getURL();

40

41

/**

42

* Get the server URI

43

* @return Server URI

44

*/

45

URI getURI();

46

47

/**

48

* Get the context path URI for the server

49

* @return URI including context path if configured

50

*/

51

URI getContextURI();

52

53

/**

54

* Check if the server should remain alive after startup

55

* @return true if server should keep the JVM alive

56

*/

57

boolean isKeepAlive();

58

}

59

```

60

61

**Usage Examples:**

62

63

```java

64

import io.micronaut.runtime.server.EmbeddedServer;

65

import io.micronaut.runtime.Micronaut;

66

67

public class ServerInfoExample {

68

69

public static void main(String[] args) {

70

ApplicationContext context = Micronaut.run(ServerInfoExample.class, args);

71

72

// Get embedded server information

73

EmbeddedServer server = context.getBean(EmbeddedServer.class);

74

75

System.out.println("Server Details:");

76

System.out.println(" URL: " + server.getURL());

77

System.out.println(" Host: " + server.getHost());

78

System.out.println(" Port: " + server.getPort());

79

System.out.println(" Scheme: " + server.getScheme());

80

System.out.println(" Context URI: " + server.getContextURI());

81

System.out.println(" Keep Alive: " + server.isKeepAlive());

82

System.out.println(" Running: " + server.isRunning());

83

}

84

}

85

86

// Service that uses server information

87

@Singleton

88

public class ServiceRegistrationService {

89

90

private final EmbeddedServer server;

91

92

public ServiceRegistrationService(EmbeddedServer server) {

93

this.server = server;

94

}

95

96

public void registerWithServiceDiscovery() {

97

String serviceUrl = server.getURL().toString();

98

99

// Register this service instance

100

ServiceRegistry.register(

101

"my-service",

102

serviceUrl,

103

Map.of(

104

"host", server.getHost(),

105

"port", String.valueOf(server.getPort()),

106

"scheme", server.getScheme()

107

)

108

);

109

}

110

}

111

```

112

113

### Server Lifecycle Events

114

115

Events fired during embedded server startup and shutdown phases.

116

117

```java { .api }

118

/**

119

* Event fired when EmbeddedServer completes startup

120

* Indicates server is ready to accept HTTP requests

121

*/

122

public class ServerStartupEvent extends ApplicationStartupEvent {

123

124

/**

125

* Create server startup event

126

* @param embeddedServer The server that completed startup

127

*/

128

public ServerStartupEvent(EmbeddedServer embeddedServer);

129

130

/**

131

* Get the embedded server that started

132

* @return EmbeddedServer instance

133

*/

134

@Override

135

public EmbeddedServer getSource();

136

}

137

138

/**

139

* Event fired when EmbeddedServer begins shutdown

140

* Server will no longer accept new requests after this event

141

*/

142

public class ServerShutdownEvent extends ApplicationEvent {

143

144

/**

145

* Create server shutdown event

146

* @param embeddedServer The server that is shutting down

147

*/

148

public ServerShutdownEvent(EmbeddedServer embeddedServer);

149

150

/**

151

* Get the embedded server that is shutting down

152

* @return EmbeddedServer instance

153

*/

154

@Override

155

public EmbeddedServer getSource();

156

}

157

```

158

159

**Usage Examples:**

160

161

```java

162

import io.micronaut.runtime.server.event.ServerStartupEvent;

163

import io.micronaut.runtime.server.event.ServerShutdownEvent;

164

import io.micronaut.runtime.event.annotation.EventListener;

165

166

@Singleton

167

public class ServerLifecycleManager {

168

169

private static final Logger logger = LoggerFactory.getLogger(ServerLifecycleManager.class);

170

171

@EventListener

172

public void onServerStartup(ServerStartupEvent event) {

173

EmbeddedServer server = event.getSource();

174

175

logger.info("πŸš€ Server started successfully!");

176

logger.info(" Server URL: {}", server.getURL());

177

logger.info(" Host: {}", server.getHost());

178

logger.info(" Port: {}", server.getPort());

179

logger.info(" Scheme: {}", server.getScheme());

180

181

// Perform startup tasks

182

initializeHealthChecks(server);

183

registerWithLoadBalancer(server);

184

enableTrafficRouting(server);

185

186

// Log startup time

187

long startupTime = getStartupTime();

188

logger.info("βœ… Server ready in {}ms", startupTime);

189

}

190

191

@EventListener

192

public void onServerShutdown(ServerShutdownEvent event) {

193

EmbeddedServer server = event.getSource();

194

195

logger.info("πŸ›‘ Server shutdown initiated");

196

logger.info(" Server URL: {}", server.getURL());

197

198

// Perform graceful shutdown tasks

199

deregisterFromLoadBalancer(server);

200

disableTrafficRouting(server);

201

completeOngoingRequests();

202

closeConnections();

203

204

logger.info("βœ… Server shutdown completed");

205

}

206

207

private void initializeHealthChecks(EmbeddedServer server) {

208

// Start health check endpoints

209

healthCheckService.start(server.getPort());

210

}

211

212

private void registerWithLoadBalancer(EmbeddedServer server) {

213

// Register with external load balancer

214

loadBalancerClient.register(

215

server.getHost(),

216

server.getPort(),

217

server.getScheme()

218

);

219

}

220

}

221

```

222

223

### Server Configuration Integration

224

225

Working with server configuration and customization.

226

227

```java { .api }

228

/**

229

* Server configuration integration examples

230

* Accessing and using server configuration

231

*/

232

233

// Configuration-driven server behavior

234

@Singleton

235

public class ServerConfigurationService {

236

237

private final ServerConfiguration serverConfig;

238

private final EmbeddedServer embeddedServer;

239

240

public ServerConfigurationService(ServerConfiguration serverConfig,

241

EmbeddedServer embeddedServer) {

242

this.serverConfig = serverConfig;

243

this.embeddedServer = embeddedServer;

244

}

245

246

@EventListener

247

public void onServerStartup(ServerStartupEvent event) {

248

// Validate server configuration matches expectations

249

validateServerConfiguration();

250

251

// Configure server-specific features

252

configureServerFeatures();

253

}

254

255

private void validateServerConfiguration() {

256

int actualPort = embeddedServer.getPort();

257

int configuredPort = serverConfig.getPort();

258

259

if (actualPort != configuredPort) {

260

logger.warn("Server started on port {} but configured for port {}",

261

actualPort, configuredPort);

262

}

263

264

String actualHost = embeddedServer.getHost();

265

String configuredHost = serverConfig.getHost();

266

267

if (!Objects.equals(actualHost, configuredHost)) {

268

logger.info("Server host: actual={}, configured={}",

269

actualHost, configuredHost);

270

}

271

}

272

}

273

274

// Custom server startup logic

275

@Singleton

276

public class CustomServerStartup {

277

278

@EventListener

279

public void onServerStartup(ServerStartupEvent event) {

280

EmbeddedServer server = event.getSource();

281

282

// Custom initialization based on server properties

283

if ("https".equals(server.getScheme())) {

284

enableSecurityFeatures();

285

}

286

287

if (server.getPort() == 443 || server.getPort() == 80) {

288

enableProductionMode();

289

}

290

291

// Register custom endpoints

292

registerCustomEndpoints(server);

293

}

294

295

private void registerCustomEndpoints(EmbeddedServer server) {

296

String baseUrl = server.getURL().toString();

297

298

// Register metrics endpoint

299

endpointRegistry.register(baseUrl + "/metrics", metricsHandler);

300

301

// Register admin endpoint

302

if (isAdminEnabled()) {

303

endpointRegistry.register(baseUrl + "/admin", adminHandler);

304

}

305

}

306

}

307

```

308

309

### Server Environment Integration

310

311

Integration with different server environments and deployment scenarios.

312

313

```java { .api }

314

@Singleton

315

public class EnvironmentAwareServerManager {

316

317

private final Environment environment;

318

319

public EnvironmentAwareServerManager(Environment environment) {

320

this.environment = environment;

321

}

322

323

@EventListener

324

public void onServerStartup(ServerStartupEvent event) {

325

EmbeddedServer server = event.getSource();

326

327

// Environment-specific server configuration

328

if (environment.getActiveNames().contains("production")) {

329

configureProductionServer(server);

330

} else if (environment.getActiveNames().contains("development")) {

331

configureDevelopmentServer(server);

332

}

333

334

// Cloud environment detection

335

if (isRunningInCloud()) {

336

configureCloudServer(server);

337

}

338

339

// Container environment detection

340

if (isRunningInContainer()) {

341

configureContainerServer(server);

342

}

343

}

344

345

private void configureProductionServer(EmbeddedServer server) {

346

logger.info("Configuring server for production environment");

347

348

// Enable production features

349

enableRequestLogging();

350

enablePerformanceMonitoring();

351

configureSecurityHeaders();

352

353

// Validate production requirements

354

if (!"https".equals(server.getScheme())) {

355

logger.warn("Production server not using HTTPS: {}", server.getURL());

356

}

357

}

358

359

private void configureDevelopmentServer(EmbeddedServer server) {

360

logger.info("Configuring server for development environment");

361

362

// Enable development features

363

enableDebugEndpoints();

364

enableHotReload();

365

disableSecurityRestrictions();

366

367

logger.info("Development server ready at: {}", server.getURL());

368

}

369

370

private boolean isRunningInCloud() {

371

// Detect cloud environment (AWS, GCP, Azure, etc.)

372

return environment.getProperty("cloud.platform").isPresent() ||

373

System.getenv("AWS_REGION") != null ||

374

System.getenv("GOOGLE_CLOUD_PROJECT") != null;

375

}

376

377

private boolean isRunningInContainer() {

378

// Detect container environment (Docker, Kubernetes, etc.)

379

return Files.exists(Paths.get("/.dockerenv")) ||

380

System.getenv("KUBERNETES_SERVICE_HOST") != null;

381

}

382

}

383

```

384

385

### Server Health and Monitoring

386

387

Integration with health checks and monitoring systems.

388

389

```java { .api }

390

@Singleton

391

public class ServerHealthManager {

392

393

private final MeterRegistry meterRegistry;

394

private final HealthAggregator healthAggregator;

395

396

public ServerHealthManager(MeterRegistry meterRegistry,

397

HealthAggregator healthAggregator) {

398

this.meterRegistry = meterRegistry;

399

this.healthAggregator = healthAggregator;

400

}

401

402

@EventListener

403

public void onServerStartup(ServerStartupEvent event) {

404

EmbeddedServer server = event.getSource();

405

406

// Register server metrics

407

registerServerMetrics(server);

408

409

// Initialize health checks

410

initializeHealthChecks(server);

411

412

// Start monitoring

413

startServerMonitoring(server);

414

}

415

416

private void registerServerMetrics(EmbeddedServer server) {

417

// Server information gauges

418

Gauge.builder("server.port")

419

.description("Server port number")

420

.register(meterRegistry, server, s -> s.getPort());

421

422

Gauge.builder("server.running")

423

.description("Server running status")

424

.register(meterRegistry, server, s -> s.isRunning() ? 1 : 0);

425

426

// Server startup timer

427

Timer.Sample startupTimer = Timer.start(meterRegistry);

428

startupTimer.stop(Timer.builder("server.startup.time")

429

.description("Server startup time")

430

.register(meterRegistry));

431

}

432

433

private void initializeHealthChecks(EmbeddedServer server) {

434

// Register server-specific health indicators

435

healthAggregator.addHealthIndicator("server", () ->

436

server.isRunning() ?

437

HealthStatus.UP.describe("Server running on " + server.getURL()) :

438

HealthStatus.DOWN.describe("Server not running")

439

);

440

441

// Port availability check

442

healthAggregator.addHealthIndicator("server.port", () ->

443

isPortAccessible(server.getHost(), server.getPort()) ?

444

HealthStatus.UP.describe("Port " + server.getPort() + " accessible") :

445

HealthStatus.DOWN.describe("Port " + server.getPort() + " not accessible")

446

);

447

}

448

449

@EventListener

450

public void onServerShutdown(ServerShutdownEvent event) {

451

// Record shutdown metrics

452

meterRegistry.counter("server.shutdown.count").increment();

453

454

// Update health status

455

healthAggregator.updateHealthIndicator("server",

456

HealthStatus.DOWN.describe("Server shutting down"));

457

}

458

}

459

```

460

461

### Integration with External Systems

462

463

Examples of integrating server lifecycle with external systems.

464

465

```java { .api }

466

@Singleton

467

public class ExternalSystemIntegration {

468

469

private final ServiceDiscoveryClient serviceDiscovery;

470

private final LoadBalancerClient loadBalancer;

471

private final MetricsCollector metricsCollector;

472

473

@EventListener

474

@Async

475

public CompletableFuture<Void> onServerStartup(ServerStartupEvent event) {

476

return CompletableFuture.runAsync(() -> {

477

EmbeddedServer server = event.getSource();

478

479

try {

480

// Register with service discovery

481

registerWithServiceDiscovery(server);

482

483

// Add to load balancer pool

484

addToLoadBalancerPool(server);

485

486

// Start external monitoring

487

startExternalMonitoring(server);

488

489

logger.info("Server successfully registered with external systems");

490

} catch (Exception e) {

491

logger.error("Failed to register with external systems", e);

492

// Could trigger health check failure or retry logic

493

}

494

});

495

}

496

497

@EventListener

498

@Async

499

public CompletableFuture<Void> onServerShutdown(ServerShutdownEvent event) {

500

return CompletableFuture.runAsync(() -> {

501

EmbeddedServer server = event.getSource();

502

503

try {

504

// Graceful deregistration from external systems

505

removeFromLoadBalancerPool(server);

506

deregisterFromServiceDiscovery(server);

507

stopExternalMonitoring(server);

508

509

logger.info("Server successfully deregistered from external systems");

510

} catch (Exception e) {

511

logger.error("Error during external system deregistration", e);

512

}

513

});

514

}

515

516

private void registerWithServiceDiscovery(EmbeddedServer server) {

517

ServiceInstance instance = ServiceInstance.builder()

518

.instanceId(generateInstanceId())

519

.serviceName("my-service")

520

.host(server.getHost())

521

.port(server.getPort())

522

.secure("https".equals(server.getScheme()))

523

.metadata(Map.of(

524

"version", getApplicationVersion(),

525

"environment", getCurrentEnvironment(),

526

"contextPath", server.getContextURI().getPath()

527

))

528

.build();

529

530

serviceDiscovery.register(instance);

531

}

532

}

533

```