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

db.stream() has no timeout #565

Closed
alxndrsn opened this issue Aug 7, 2022 · 5 comments · Fixed by #599
Closed

db.stream() has no timeout #565

alxndrsn opened this issue Aug 7, 2022 · 5 comments · Fixed by #599

Comments

@alxndrsn
Copy link
Contributor

alxndrsn commented Aug 7, 2022

Currently there is no timeout on database stream connections.

This can be observed by patching gajus/slonik#347 and then creating a large number of slow, streamed connections (e.g. submission zip export), until central-backend stops responding to requests. You can check for open connections in postgres with SELECT COUNT(*) FROM pg_stat_activity;.

This may be because the version of Slonik currently in-use has various timeout settings disabled.

Slonik does not appear to implement its own stream timeout functionality.

It seems like slonik streams use pg-cursor under the hood, which may use postgres cusrors. I haven't found clear documentation of how/if postgres cursors are timed out. However, when the lockup occurs there are clear, relevant entries in both pg_stat_activity and pg_locks, but there are no rows returned by SELECT * FROM pg_cursors;. This may mean that PostgreSQL Cursors are not actually being used.

Timeouts might not be necessary if central-backend reliably destroys streams in all code paths. It's hinted this may not be the case at https://github.com/getodk/central-backend/blob/master/lib/resources/submissions.js#L282. Either way, it might be pragmatic to add timeout handling in lib/util/db.js.

Related:

@issa-tseng
Copy link
Member

issa-tseng commented Aug 7, 2022 via email

@matthew-white
Copy link
Member

if the client decides to never time out that’s a problem but i think nginx will in most cases.

From what I've seen, the nginx timeout doesn't have an effect on Backend: it doesn't actually terminate active queries. For example, if you send a non-GET request, and the nginx timeout kicks in, then the client will receive an error response; but Backend will continue working on the request. That means that despite the error response, the request may ultimately have its intended effect.

@alxndrsn
Copy link
Contributor Author

alxndrsn commented Aug 8, 2022

From what I've seen, the nginx timeout doesn't have an effect on Backend: it doesn't actually terminate active queries.

I'm observing the same.

if you send a non-GET request, and the nginx timeout kicks in, then the client will receive an error response; but Backend will continue working on the request

@matthew-white is the behaviour different for GET requests?

@matthew-white
Copy link
Member

is the behaviour different for GET requests?

I only remember seeing this for non-GET requests, but I would guess that it's the same for GET requests.

@matthew-white
Copy link
Member

Closed by #604.

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 a pull request may close this issue.

3 participants