0
# Server Engine Abstraction
1
2
Engine abstraction layer for different server implementations providing a unified interface for HTTP server management, environment configuration, and connector setup for various server backends like Netty, Jetty, and CIO.
3
4
## Capabilities
5
6
### Application Engine Interface
7
8
Core interface for server engine implementations providing lifecycle management and environment access.
9
10
```kotlin { .api }
11
/**
12
* Interface for server engine implementations
13
*/
14
interface ApplicationEngine {
15
/** Application engine environment */
16
val environment: ApplicationEngineEnvironment
17
18
/** Start the server engine */
19
fun start(wait: Boolean = true): ApplicationEngine
20
/** Stop the server engine */
21
fun stop(gracePeriodMillis: Long, timeoutMillis: Long)
22
/** Add shutdown hook */
23
fun addShutdownHook(hook: () -> Unit)
24
}
25
26
/**
27
* Base implementation for application engines
28
*/
29
abstract class BaseApplicationEngine(
30
final override val environment: ApplicationEngineEnvironment,
31
val pipeline: EnginePipeline = defaultEnginePipeline(environment)
32
) : ApplicationEngine {
33
/** Engine is running */
34
val isRunning: Boolean
35
/** Engine monitor for lifecycle events */
36
val monitor: Events
37
38
/** Execute engine pipeline */
39
protected suspend fun executeEngine(call: ApplicationCall)
40
/** Start engine implementation */
41
protected abstract fun start(wait: Boolean): ApplicationEngine
42
/** Stop engine implementation */
43
protected abstract fun stop(gracePeriodMillis: Long, timeoutMillis: Long)
44
}
45
```
46
47
### Application Engine Environment
48
49
Environment configuration for application engines including connectors, modules, and application lifecycle.
50
51
```kotlin { .api }
52
/**
53
* Environment for application engines
54
*/
55
interface ApplicationEngineEnvironment {
56
/** Application instance */
57
val application: Application
58
/** Environment logger */
59
val log: Logger
60
/** Environment configuration */
61
val config: ApplicationConfig
62
/** Event monitor */
63
val monitor: Events
64
/** Development mode flag */
65
val developmentMode: Boolean
66
/** Server connectors configuration */
67
val connectors: List<EngineConnectorConfig>
68
/** Application modules to load */
69
val modules: List<Application.() -> Unit>
70
/** Parent coroutine context */
71
val parentCoroutineContext: CoroutineContext
72
/** Watch paths for development mode */
73
val watchPatterns: List<String>
74
/** Root path for the application */
75
val rootPath: String
76
}
77
78
/**
79
* Builder for creating engine environments
80
*/
81
class ApplicationEngineEnvironmentBuilder {
82
/** Set parent coroutine context */
83
var parentCoroutineContext: CoroutineContext = EmptyCoroutineContext
84
/** Set development mode */
85
var developmentMode: Boolean = false
86
/** Set root path */
87
var rootPath: String = "/"
88
/** Watch patterns for auto-reload */
89
val watchPatterns: MutableList<String> = mutableListOf()
90
/** Connector configurations */
91
val connectors: MutableList<EngineConnectorConfig> = mutableListOf()
92
/** Application modules */
93
val modules: MutableList<Application.() -> Unit> = mutableListOf()
94
95
/** Add HTTP connector */
96
fun connector(block: EngineConnectorConfigBuilder.() -> Unit)
97
/** Add application module */
98
fun module(body: Application.() -> Unit)
99
/** Build environment */
100
fun build(): ApplicationEngineEnvironment
101
}
102
```
103
104
### Engine Connectors
105
106
Configuration for HTTP/HTTPS connectors with customizable host, port, and protocol settings.
107
108
```kotlin { .api }
109
/**
110
* Engine connector configuration
111
*/
112
interface EngineConnectorConfig {
113
/** Connector type (HTTP, HTTPS) */
114
val type: ConnectorType
115
/** Server host */
116
val host: String
117
/** Server port */
118
val port: Int
119
}
120
121
/**
122
* Builder for engine connector configuration
123
*/
124
class EngineConnectorConfigBuilder {
125
/** Connector host (default: 0.0.0.0) */
126
var host: String = "0.0.0.0"
127
/** Connector port (default: 80) */
128
var port: Int = 80
129
130
/** Build connector configuration */
131
fun build(): EngineConnectorConfig
132
}
133
134
/**
135
* Connector types
136
*/
137
enum class ConnectorType {
138
HTTP,
139
HTTPS
140
}
141
142
/**
143
* HTTP connector configuration
144
*/
145
class HttpConnectorConfig(
146
override val host: String = "0.0.0.0",
147
override val port: Int = 80
148
) : EngineConnectorConfig {
149
override val type: ConnectorType = ConnectorType.HTTP
150
}
151
152
/**
153
* HTTPS connector configuration
154
*/
155
class HttpsConnectorConfig(
156
override val host: String = "0.0.0.0",
157
override val port: Int = 443,
158
val keyStorePath: String,
159
val keyStorePassword: String,
160
val privateKeyPassword: String? = null
161
) : EngineConnectorConfig {
162
override val type: ConnectorType = ConnectorType.HTTPS
163
}
164
```
165
166
### Engine Pipeline
167
168
Pipeline system for processing HTTP requests at the engine level before application processing.
169
170
```kotlin { .api }
171
/**
172
* Engine pipeline for request processing
173
*/
174
class EnginePipeline : Pipeline<Unit, ApplicationCall> {
175
companion object {
176
/** Before phase for engine pre-processing */
177
val Before: PipelinePhase = PipelinePhase("Before")
178
/** Call phase for application call processing */
179
val Call: PipelinePhase = PipelinePhase("Call")
180
/** After phase for engine post-processing */
181
val After: PipelinePhase = PipelinePhase("After")
182
}
183
}
184
185
/**
186
* Create default engine pipeline
187
* @param environment - Engine environment
188
* @return Configured engine pipeline
189
*/
190
fun defaultEnginePipeline(environment: ApplicationEngineEnvironment): EnginePipeline
191
```
192
193
### Command Line Configuration
194
195
Utilities for parsing command line arguments and configuring engines from command line options.
196
197
```kotlin { .api }
198
/**
199
* Command line configuration parser
200
*/
201
class CommandLineConfig(args: Array<String>) {
202
/** Parsed configuration */
203
val config: ApplicationConfig
204
/** Server host from command line */
205
val host: String?
206
/** Server port from command line */
207
val port: Int?
208
/** Development mode flag */
209
val developmentMode: Boolean
210
/** Watch patterns from command line */
211
val watchPatterns: List<String>
212
213
/** Create engine environment from command line */
214
fun createEnvironment(): ApplicationEngineEnvironment
215
}
216
217
/**
218
* Parse command line arguments
219
* @param args - Command line arguments array
220
* @return Parsed command line configuration
221
*/
222
fun parseCommandLineArgs(args: Array<String>): CommandLineConfig
223
```
224
225
### Environment Utilities
226
227
Utility functions for creating and configuring application engine environments.
228
229
```kotlin { .api }
230
/**
231
* Create application engine environment
232
* @param configure - Environment configuration block
233
* @return Configured environment
234
*/
235
fun applicationEngineEnvironment(configure: ApplicationEngineEnvironmentBuilder.() -> Unit): ApplicationEngineEnvironment
236
237
/**
238
* Create development environment with auto-reload
239
* @param configure - Environment configuration block
240
* @return Development environment
241
*/
242
fun developmentEnvironment(configure: ApplicationEngineEnvironmentBuilder.() -> Unit): ApplicationEngineEnvironment
243
244
/**
245
* Create production environment
246
* @param configure - Environment configuration block
247
* @return Production environment
248
*/
249
fun productionEnvironment(configure: ApplicationEngineEnvironmentBuilder.() -> Unit): ApplicationEngineEnvironment
250
```
251
252
### Engine Events
253
254
Event system for engine lifecycle monitoring and health checking.
255
256
```kotlin { .api }
257
/**
258
* Engine lifecycle events
259
*/
260
object EngineEvents {
261
/** Engine starting event */
262
val EngineStarting: EventDefinition<ApplicationEngine>
263
/** Engine started event */
264
val EngineStarted: EventDefinition<ApplicationEngine>
265
/** Engine stopping event */
266
val EngineStopping: EventDefinition<ApplicationEngine>
267
/** Engine stopped event */
268
val EngineStopped: EventDefinition<ApplicationEngine>
269
}
270
271
/**
272
* Event monitoring for engines
273
*/
274
interface Events {
275
/** Subscribe to event */
276
fun <T> subscribe(definition: EventDefinition<T>, handler: (T) -> Unit)
277
/** Unsubscribe from event */
278
fun <T> unsubscribe(definition: EventDefinition<T>, handler: (T) -> Unit)
279
/** Raise event */
280
fun <T> raise(definition: EventDefinition<T>, value: T)
281
}
282
283
/**
284
* Event definition
285
*/
286
data class EventDefinition<T>(val name: String)
287
```
288
289
**Usage Examples:**
290
291
```kotlin
292
import io.ktor.server.application.*
293
import io.ktor.server.engine.*
294
import io.ktor.server.response.*
295
import io.ktor.server.routing.*
296
297
// Basic engine environment setup
298
fun createBasicEnvironment(): ApplicationEngineEnvironment {
299
return applicationEngineEnvironment {
300
// Add HTTP connector
301
connector {
302
host = "0.0.0.0"
303
port = 8080
304
}
305
306
// Add application module
307
module {
308
routing {
309
get("/") {
310
call.respondText("Hello from Ktor!")
311
}
312
}
313
}
314
}
315
}
316
317
// Development environment with auto-reload
318
fun createDevelopmentEnvironment(): ApplicationEngineEnvironment {
319
return developmentEnvironment {
320
developmentMode = true
321
322
// Watch for changes
323
watchPatterns += "src/main/kotlin/**/*.kt"
324
watchPatterns += "src/main/resources/**/*"
325
326
connector {
327
host = "localhost"
328
port = 8080
329
}
330
331
module(Application::developmentModule)
332
}
333
}
334
335
// Production environment with HTTPS
336
fun createProductionEnvironment(): ApplicationEngineEnvironment {
337
return productionEnvironment {
338
developmentMode = false
339
340
// HTTP connector (for redirects)
341
connector {
342
host = "0.0.0.0"
343
port = 80
344
}
345
346
// HTTPS connector
347
connector {
348
host = "0.0.0.0"
349
port = 443
350
// Note: HTTPS configuration would be engine-specific
351
}
352
353
module(Application::productionModule)
354
}
355
}
356
357
// Multiple connectors setup
358
fun createMultiConnectorEnvironment(): ApplicationEngineEnvironment {
359
return applicationEngineEnvironment {
360
// Public HTTP connector
361
connector {
362
host = "0.0.0.0"
363
port = 8080
364
}
365
366
// Admin connector on different port
367
connector {
368
host = "127.0.0.1"
369
port = 8081
370
}
371
372
module {
373
routing {
374
get("/") {
375
call.respondText("Public API")
376
}
377
378
get("/admin") {
379
// Check if request came from admin connector
380
val localPort = call.request.local.port
381
if (localPort == 8081) {
382
call.respondText("Admin Interface")
383
} else {
384
call.respond(HttpStatusCode.NotFound)
385
}
386
}
387
}
388
}
389
}
390
}
391
392
// Command line configuration
393
fun main(args: Array<String>) {
394
val commandLineConfig = parseCommandLineArgs(args)
395
val environment = commandLineConfig.createEnvironment()
396
397
// Engine would be started here with the environment
398
// Example: embeddedServer(Netty, environment).start(wait = true)
399
}
400
401
// Custom engine implementation example
402
abstract class CustomApplicationEngine(
403
environment: ApplicationEngineEnvironment
404
) : BaseApplicationEngine(environment) {
405
406
override fun start(wait: Boolean): ApplicationEngine {
407
// Subscribe to engine events
408
environment.monitor.subscribe(EngineEvents.EngineStarting) { engine ->
409
environment.log.info("Starting custom engine...")
410
}
411
412
environment.monitor.subscribe(EngineEvents.EngineStarted) { engine ->
413
environment.log.info("Custom engine started on ${environment.connectors.joinToString { "${it.host}:${it.port}" }}")
414
}
415
416
// Start server implementation
417
startServer()
418
419
if (wait) {
420
// Wait for shutdown
421
Runtime.getRuntime().addShutdownHook(Thread {
422
stop(1000, 5000)
423
})
424
}
425
426
return this
427
}
428
429
override fun stop(gracePeriodMillis: Long, timeoutMillis: Long) {
430
environment.monitor.raise(EngineEvents.EngineStopping, this)
431
432
// Stop server implementation
433
stopServer(gracePeriodMillis, timeoutMillis)
434
435
environment.monitor.raise(EngineEvents.EngineStopped, this)
436
}
437
438
protected abstract fun startServer()
439
protected abstract fun stopServer(gracePeriodMillis: Long, timeoutMillis: Long)
440
}
441
442
// Environment with custom configuration
443
fun createConfigurableEnvironment(config: ApplicationConfig): ApplicationEngineEnvironment {
444
return applicationEngineEnvironment {
445
// Load configuration
446
val serverConfig = config.config("server")
447
val host = serverConfig.property("host").getString()
448
val port = serverConfig.property("port").getInt()
449
450
connector {
451
this.host = host
452
this.port = port
453
}
454
455
// Set development mode from config
456
developmentMode = config.propertyOrNull("app.development")?.getBoolean() ?: false
457
458
// Set root path from config
459
rootPath = config.propertyOrNull("app.rootPath")?.getString() ?: "/"
460
461
// Load modules based on configuration
462
val enabledModules = config.propertyOrNull("app.modules")?.getList() ?: emptyList()
463
464
if ("routing" in enabledModules) {
465
module(Application::routingModule)
466
}
467
468
if ("authentication" in enabledModules) {
469
module(Application::authenticationModule)
470
}
471
472
if ("monitoring" in enabledModules) {
473
module(Application::monitoringModule)
474
}
475
}
476
}
477
478
// Extension modules
479
fun Application.developmentModule() {
480
routing {
481
get("/") {
482
call.respondText("Development Server")
483
}
484
485
get("/reload") {
486
call.respondText("Auto-reload enabled")
487
}
488
}
489
}
490
491
fun Application.productionModule() {
492
routing {
493
get("/") {
494
call.respondText("Production Server")
495
}
496
497
get("/health") {
498
call.respond(HttpStatusCode.OK, mapOf("status" to "healthy"))
499
}
500
}
501
}
502
503
fun Application.routingModule() {
504
routing {
505
get("/api/status") {
506
call.respond(mapOf("service" to "running"))
507
}
508
}
509
}
510
511
fun Application.authenticationModule() {
512
// Authentication setup would go here
513
}
514
515
fun Application.monitoringModule() {
516
// Monitoring and metrics setup would go here
517
}
518
```