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

Seamail Pagination Hangs #239

Closed
cohoe opened this issue Dec 6, 2023 · 4 comments
Closed

Seamail Pagination Hangs #239

cohoe opened this issue Dec 6, 2023 · 4 comments
Assignees
Labels
bug Something isn't working high priority Something that really should be implemented NowTM
Milestone

Comments

@cohoe
Copy link
Member

cohoe commented Dec 6, 2023

If I paginate with a small-ish limit through seamail (/api/v3/fez/joined?type=open&type=closed&limit=10), the first page loads, But subsequent pages specified with a &start=X hang. This can be replicated on the Beta.

When I mashed reload and spam clicked, I started to see 500 errors related to connection pools.

[ WARNING ] HTTPClientError.getConnectionFromPoolTimeout [request-id: 06A4441A-9A2C-4E0E-AC8E-AF6988ADD0BF]

Feels like a thread lock? Had to bounce the container in order to get any responses.

Fortunately the default page size of 50 is likely large enough that general users would not notice (would need to have 50+ seamail conversations).

@cohoe cohoe added bug Something isn't working high priority Something that really should be implemented NowTM labels Dec 6, 2023
@cohoe
Copy link
Member Author

cohoe commented Jan 5, 2024

I just encountered this same behavior working on #214

Totally new endpoint, request comes in and never responds

@cohoe cohoe added this to the 2024 Sailing milestone Jan 5, 2024
@cohoe
Copy link
Member Author

cohoe commented Jan 5, 2024

This seems to be triggered by calling both .range() with a non-zero start and .count() on the same query object. If I do something like this:

let queryForTotal = ModeratorAction.query(on: req.db)
async let totalActionCount = try queryForTotal.count()

let query = ModeratorAction.query(on: req.db)
async let result = try query.range(start..<(start + limit)).sort(\.$createdAt, .descending).all().map { try ModeratorActionLogData(action: $0, on: req) }

Then it works just fine. Compared to:

let query = ModeratorAction.query(on: req.db)
async let totalActionCount = try queryForTotal.count()
async let result = try query.range(start..<(start + limit)).sort(\.$createdAt, .descending).all().map { try ModeratorActionLogData(action: $0, on: req) }

Which hangs infinitely as soon as start is not 0. WTF?!

cohoe added a commit to cohoe/swiftarr that referenced this issue Jan 5, 2024
@cohoe
Copy link
Member Author

cohoe commented Jan 5, 2024

I think I had a breakthrough on this. Something with the async/await keywords used for those particular calls. Switching to:

let query = ModeratorAction.query(on: req.db)
let totalActionCount = try await queryForTotal.count()
let result = try await query.range(start..<(start + limit)).sort(\.$createdAt, .descending).all().map { try ModeratorActionLogData(action: $0, on: req) }

Works just fine

@cohoe
Copy link
Member Author

cohoe commented Jan 5, 2024

Nope. Thanks to some ChatGPTing today I learned:

async let foo = try doAsyncOperation()

This syntax is used to perform asynchronous operations in parallel. The doAsyncOperation() function will be called asynchronously, and the result will be assigned to foo when it becomes available. The rest of the code can continue executing while waiting for the asynchronous operation to complete.

let foo = try await doAsyncOperation()

This syntax is used when you want to explicitly wait for the asynchronous operation to complete before moving on to the next line of code. It's a more sequential way of handling asynchronous code, where the await keyword is used to suspend the execution until the asynchronous operation is finished, and then the result is assigned to foo.

That's probably why we have the various query.copy()'s for the total count calculation. Otherwise we hit some race condition where it tries to .count() while still awaiting.

@cohoe cohoe self-assigned this Jan 5, 2024
cohoe added a commit to cohoe/swiftarr that referenced this issue Jan 5, 2024
@cohoe cohoe closed this as completed in 7eea0b9 Jan 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working high priority Something that really should be implemented NowTM
Projects
None yet
Development

No branches or pull requests

1 participant