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

Drop unsafe from PQconsumeInput FFI import #9

Merged
merged 1 commit into from
Jul 29, 2020

Conversation

ulidtko
Copy link
Contributor

@ulidtko ulidtko commented Jul 10, 2020

Hi @phadej!

I've been doing performance testing of PostgREST (which indirectly uses this library) with GHC 8.10.1 (and 8.8.3 too). We have a latency spikes issue with it, easily attributable to idle GC pauses. That is, tens-to-hundreds-of-milliseconds long stop-the-haskell-world episodes when the GC is not using the CPU; is idle; blocked.

You can check out my methods & intermediate results in this thread: https://gitlab.haskell.org/ghc/ghc/-/issues/18415

While I currently cannot completely explain all the idle pauses — it's 100% clear that one of contributing issues is this line here in postgresql-libpq. As the commit message says: PQconsumeInput() in libpq.so can go into blocking IO. While the GHC User Guide isn't terribly clear on how FFI interacts with GC, you can see this doc patch and this graph. All together, this leads to the conclusion that the import of PQconsumeInput should not be marked unsafe.

Sure thing, I did test this change (and not only it). It's a bit hard to summarize concisely — but if you let me hand-pick a few graphs, I'd say that this one is "typical" for the code in master:

vegeta-plot-1kRPS-PQconsumeInput-unsafe

The vertical axis is latency of PostgREST handling HTTP requests; red lines are 10s timeouts. 1000 requests-per-second load; everything run on a modest SSD laptop, without CPU saturation. Here's a similar graph for a build with this patch applied:

vegeta-plot-1kRPS-allsafe

(Well actually, all postgresql-libpq imports are unmarked unsafe in the latter graph; but only PQconsumeInput matters.)

Might not seem significant (and I can pick way more dramatic graphs) — but when I drill down into threadscope profiles, this patch does eliminate places like this.

Please review, merge & release.

Some paths in PQconsumeInput can go into blocking I/O calls.

This has really bad interactions with GC; the RTS ends up waiting on IO
(potentially, network) before being able to start Garbage Collection --
meanwhile, any Haskell mutation is blocked all this time.

See the related research in: https://gitlab.haskell.org/ghc/ghc/-/issues/18415

Regardless of further issues in GHC RTS -- this call *must not* be marked "unsafe".
@phadej
Copy link
Collaborator

phadej commented Jul 10, 2020

This makes sense. Potentially blocking / "slow" FFI calls shouldn't be unsafe

  • I think this should be safe, as we don't give it Ptr PGConn which may move
  • I'll check the rest of the bindings too first though.

Please me ping me again, if I don't act during July.

@ulidtko
Copy link
Contributor Author

ulidtko commented Jul 29, 2020

Hey @phadej ping :) I know there're conferences and such... Pinging as you requested.

I did already check all the bindings (what they do on libpq-side) — and my judgment is, that they can be mostly left with unsafe as is, for efficiency. The only import which needs changing is PQconsumeInput, I think we agree that it shouldn't be unsafe.

You can of course go over it once again, and recheck yourself. I'd just like to land this PR sooner rather than later :)

@phadej phadej merged commit 4bf5ff8 into haskellari:master Jul 29, 2020
@phadej
Copy link
Collaborator

phadej commented Jul 29, 2020

I'll make release hopefully soon. Have to check on Windows with newer Win32 version, i.e .adopt to upcoming GHC-9.0 release.

@ulidtko ulidtko deleted the fix-unsafe-pqconsumeinput branch July 29, 2020 14:41
@phadej
Copy link
Collaborator

phadej commented Nov 2, 2020

https://hackage.haskell.org/package/postgresql-libpq-0.9.4.3 is on Hackage

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.

2 participants