Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(rt): coroutine leak in ktor engine #628

Merged
merged 1 commit into from
Apr 18, 2022
Merged

fix(rt): coroutine leak in ktor engine #628

merged 1 commit into from
Apr 18, 2022

Conversation

aajtodd
Copy link
Contributor

@aajtodd aajtodd commented Apr 18, 2022

Issue #

fixes: awslabs/aws-sdk-kotlin#587

Description of changes

Fixes a coroutine leak in the ktor engine due to invalid parent-child
relationship. The ktor engine was launching a coroutine as a child of
the request job (calLContext()). The issue was that this child
coroutine was relying on the parent job completion notification
to exit. Parent jobs can't complete though until all their children
do so the child coroutine never completed.

The ktor engine now uses the engine scope to launch this child
coroutine and establishes no parent-child relationship to the
request job explicitly.

Testing

fun main(): Unit = runBlocking {
    val executor = newFixedThreadPoolContext(1, "poll-thread")
    SqsClient { region = "us-east-1" }.use { sqs ->
        withContext(executor) {
            while(true) {
                pollQueue(sqs)
                delay(1.seconds)
            }
        }
    }

}

suspend fun pollQueue(sqs: SqsClient) {
    println("polling queue")
    val resp = sqs.receiveMessage {
        queueUrl = QUEUE_URL
        // waitTimeSeconds = 10
    }

    println("response:")
    println(resp)

    resp.messages?.forEach { m ->
        sqs.deleteMessage {
            queueUrl = QUEUE_URL
            receiptHandle = m.receiptHandle
        }
    }
}

This code polls SQS on a 1-sec interval. Before this fix you could see DefaultSqsClient slowly become the largest object (30-45+min of running):

Screen Shot 2022-04-18 at 12 34 44 PM

After this fix (and after ~45 min of running) the SQS client is the same size it was when the program started:
Screen Shot 2022-04-18 at 12 34 58 PM

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Fixes a coroutine leak in the ktor engine due to invalid parent-child
relationship. The ktor engine was launching a coroutine as a child of
the request job (`calLContext()`). The issue was that this child
coroutine was relying on the parent job completion notification
to exit. Parent jobs can't complete though until all their children
do so the child coroutine never completed.

The ktor engine now uses the engine scope to launch this child
coroutine and establishes no parent-child relationship to the
request job explicitly.

fixes: awslabs/aws-sdk-kotlin#587
@aajtodd aajtodd requested a review from a team as a code owner April 18, 2022 16:31
@aajtodd aajtodd requested review from ianbotsf and lucix-aws April 18, 2022 16:31
@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

@aajtodd aajtodd merged commit 59d0e4b into main Apr 18, 2022
@aajtodd aajtodd deleted the fix-587 branch April 18, 2022 18:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Possible memory leak in new default HTTP engine
2 participants