Skip to content

Commit 92481d6

Browse files
returnerer ikke fra shutdownhook før shutdownComplete
Etter at shutdown-signalet er sendt så vil KafkaRapid lukke consumeren, som vil medføre "partitions revoked" som igjen vil medføre at vi forsøker å committe offsets. dette er avhengig av at vi kan få lov av brannmuren (linkerd) å ha utgående http connections. så snart pre-stop-endepunktet returnerer så vil linkerd-proxy-sidecar få SIGTERM. vi har derfor en hypotese om at vi må utsette å returnere fra pre-stop-endepunktet til ETTER at kafkarapid har avsluttet HELT. ellers kan det oppstå en situasjon hvor vi tror at vi ikke klarer å committe, fordi linkerd har skrudd seg av
1 parent fc0a3d5 commit 92481d6

File tree

3 files changed

+48
-25
lines changed

3 files changed

+48
-25
lines changed

build.gradle.kts

+7-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ val logbackClassicVersion = "1.5.12"
88
val logbackEncoderVersion = "8.0"
99
val awaitilityVersion = "4.2.2"
1010
val kafkaTestcontainerVersion = "1.20.4"
11-
val tbdLibsVersion = "2024.11.29-15.07-105481e3"
11+
val tbdLibsVersion = "2024.12.18-11.39-73f8eecb"
1212

1313
group = "com.github.navikt"
1414
version = properties["version"] ?: "local-build"
@@ -54,10 +54,12 @@ kotlin {
5454
tasks {
5555
jar {
5656
manifest {
57-
attributes(mapOf(
58-
"Implementation-Title" to project.name,
59-
"Implementation-Version" to project.version
60-
))
57+
attributes(
58+
mapOf(
59+
"Implementation-Title" to project.name,
60+
"Implementation-Version" to project.version
61+
)
62+
)
6163
}
6264
}
6365
withType<Test> {

src/main/kotlin/no/nav/helse/rapids_rivers/PreStopHook.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import kotlinx.coroutines.Dispatchers
66
import kotlinx.coroutines.channels.Channel
77
import kotlinx.coroutines.channels.Channel.Factory.CONFLATED
88
import kotlinx.coroutines.channels.Channel.Factory.RENDEZVOUS
9+
import kotlinx.coroutines.delay
910
import kotlinx.coroutines.runBlocking
1011
import kotlinx.coroutines.withContext
1112
import kotlinx.coroutines.withTimeout
@@ -17,6 +18,7 @@ class PreStopHook(private val rapid: KafkaRapid) : RapidsConnection.StatusListen
1718
private companion object {
1819
val log = LoggerFactory.getLogger(this::class.java)
1920
}
21+
2022
// bruker CONFLATED som er en channel med buffer på 1, hvor hver ny melding overskriver den forrige
2123
// i praksis vil dette bety at vi ikke blokkerer senderen av shutdown-signalet
2224
private val shutdownChannel = Channel<Boolean>(CONFLATED)
@@ -25,7 +27,7 @@ class PreStopHook(private val rapid: KafkaRapid) : RapidsConnection.StatusListen
2527
rapid.register(this)
2628
}
2729

28-
override fun onShutdown(rapidsConnection: RapidsConnection) {
30+
override fun onShutdownComplete(rapidsConnection: RapidsConnection) {
2931
runBlocking(Dispatchers.IO) {
3032
try {
3133
withTimeout(1.seconds) {

src/main/kotlin/no/nav/helse/rapids_rivers/RapidApplication.kt

+38-19
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,12 @@ class RapidApplication internal constructor(
4343
}
4444
}
4545

46-
override fun onMessage(message: String, context: MessageContext, metadata: MessageMetadata, meterRegistry: MeterRegistry) {
46+
override fun onMessage(
47+
message: String,
48+
context: MessageContext,
49+
metadata: MessageMetadata,
50+
meterRegistry: MeterRegistry
51+
) {
4752
notifyMessage(message, context, metadata, meterRegistry)
4853
}
4954

@@ -54,11 +59,7 @@ class RapidApplication internal constructor(
5459
rapid.start()
5560
} finally {
5661
onKtorShutdown()
57-
val gracePeriod = 5000L
58-
val forcefulShutdownTimeout = 30000L
59-
log.info("shutting down ktor, waiting $gracePeriod ms for workers to exit. Forcing shutdown after $forcefulShutdownTimeout ms")
60-
ktor.stop(gracePeriod, forcefulShutdownTimeout)
61-
log.info("ktor shutdown complete: end of life. goodbye.")
62+
log.info("shutdown complete: end of life. goodbye.")
6263
}
6364
}
6465

@@ -113,16 +114,20 @@ class RapidApplication internal constructor(
113114
log.info("publishing $event event for app_name=$appName, instance_id=$instanceId")
114115
try {
115116
rapidsConnection.publish(it)
116-
} catch (err: Exception) { log.info("failed to publish event: {}", err.message, err) }
117+
} catch (err: Exception) {
118+
log.info("failed to publish event: {}", err.message, err)
119+
}
117120
}
118121
}
119122

120123
private fun applicationEvent(event: String): String? {
121124
if (appName == null) return null
122-
val packet = JsonMessage.newMessage(event, mapOf(
123-
"app_name" to appName,
124-
"instance_id" to instanceId
125-
))
125+
val packet = JsonMessage.newMessage(
126+
event, mapOf(
127+
"app_name" to appName,
128+
"instance_id" to instanceId
129+
)
130+
)
126131
return packet.toJson()
127132
}
128133

@@ -132,7 +137,11 @@ class RapidApplication internal constructor(
132137
fun create(
133138
env: Map<String, String>,
134139
consumerProducerFactory: ConsumerProducerFactory = ConsumerProducerFactory(AivenConfig.default),
135-
meterRegistry: PrometheusMeterRegistry = PrometheusMeterRegistry(PrometheusConfig.DEFAULT, PrometheusRegistry.defaultRegistry, Clock.SYSTEM),
140+
meterRegistry: PrometheusMeterRegistry = PrometheusMeterRegistry(
141+
PrometheusConfig.DEFAULT,
142+
PrometheusRegistry.defaultRegistry,
143+
Clock.SYSTEM
144+
),
136145
builder: Builder.() -> Unit = {},
137146
configure: (EmbeddedServer<CIOApplicationEngine, CIOApplicationEngine.Configuration>, KafkaRapid) -> Unit = { _, _ -> }
138147
): RapidsConnection {
@@ -157,9 +166,15 @@ class RapidApplication internal constructor(
157166
}
158167

159168
private fun generateAppName(env: Map<String, String>): String? {
160-
val appName = env["NAIS_APP_NAME"] ?: return log.info("not generating app name because NAIS_APP_NAME not set").let { null }
161-
val namespace = env["NAIS_NAMESPACE"] ?: return log.info("not generating app name because NAIS_NAMESPACE not set").let { null }
162-
val cluster = env["NAIS_CLUSTER_NAME"] ?: return log.info("not generating app name because NAIS_CLUSTER_NAME not set").let { null }
169+
val appName =
170+
env["NAIS_APP_NAME"] ?: return log.info("not generating app name because NAIS_APP_NAME not set")
171+
.let { null }
172+
val namespace =
173+
env["NAIS_NAMESPACE"] ?: return log.info("not generating app name because NAIS_NAMESPACE not set")
174+
.let { null }
175+
val cluster =
176+
env["NAIS_CLUSTER_NAME"] ?: return log.info("not generating app name because NAIS_CLUSTER_NAME not set")
177+
.let { null }
163178
return "$appName-$cluster-$namespace"
164179
}
165180
}
@@ -191,9 +206,10 @@ class RapidApplication internal constructor(
191206
this.ktor = ktor
192207
}
193208

194-
fun withKtor(ktor: (PreStopHook, KafkaRapid) -> EmbeddedServer<CIOApplicationEngine, CIOApplicationEngine.Configuration>) = apply {
195-
this.ktor = ktor(stopHook, rapid)
196-
}
209+
fun withKtor(ktor: (PreStopHook, KafkaRapid) -> EmbeddedServer<CIOApplicationEngine, CIOApplicationEngine.Configuration>) =
210+
apply {
211+
this.ktor = ktor(stopHook, rapid)
212+
}
197213

198214
fun withKtorModule(module: Application.() -> Unit) = apply {
199215
this.modules.add(module)
@@ -223,7 +239,10 @@ class RapidApplication internal constructor(
223239
naisEndpoints = naisEndpoints.copy(preStopEndpoint = preStopHookEndpoint)
224240
}
225241

226-
fun build(configure: (EmbeddedServer<CIOApplicationEngine, CIOApplicationEngine.Configuration>, KafkaRapid) -> Unit = { _, _ -> }, cioConfiguration: CIOApplicationEngine.Configuration.() -> Unit = { } ): RapidsConnection {
242+
fun build(
243+
configure: (EmbeddedServer<CIOApplicationEngine, CIOApplicationEngine.Configuration>, KafkaRapid) -> Unit = { _, _ -> },
244+
cioConfiguration: CIOApplicationEngine.Configuration.() -> Unit = { }
245+
): RapidsConnection {
227246
val app = ktor ?: defaultKtorApp(cioConfiguration)
228247
configure(app, rapid)
229248
with(meterRegistry) {

0 commit comments

Comments
 (0)