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

Merge 0.22 -> 0.23 #6125

Merged
merged 65 commits into from
Mar 18, 2022
Merged

Conversation

armanbilge
Copy link
Member

Check my work in the non-ember backends since I don't follow the action there too closely.

# Conflicts:
#	.github/release.yml
#	.github/workflows/ci.yml
#	async-http-client/src/test/scala/org/http4s/asynchttpclient/AsyncHttpClientSuite.scala
#	blaze-server/src/main/scala/org/http4s/blaze/server/Http1ServerStage.scala
#	blaze-server/src/main/scala/org/http4s/blaze/server/Http2NodeStage.scala
#	build.sbt
#	docs/src/main/mdoc/styles/site.css
#	ember-server/src/main/scala/org/http4s/ember/server/internal/ServerHelpers.scala
#	project/Http4sPlugin.scala
#	project/SiteConfig.scala
#	servlet/src/main/scala/org/http4s/servlet/ServletIo.scala
#	site/src/main/mdoc/docs/auth.md
#	site/src/main/mdoc/docs/client.md
#	site/src/main/mdoc/docs/json.md
#	site/src/main/mdoc/docs/middleware.md
#	site/src/main/mdoc/docs/quickstart.md
#	site/src/main/mdoc/docs/streaming.md
#	website/src/hugo/content/versions.md
#	website/src/hugo/static/_redirects

rossabaker and others added 30 commits February 8, 2022 09:56
Flush the prelude in non-blocking Servlet IO
…ually

Render continually between response prelude and body
Build tweaks in case there's another 0.21
@armanbilge armanbilge added the behind-the-scenes Appreciated, but not user-facing label Mar 14, 2022
@mergify mergify bot added the series/0.23 PRs targeting 0.23.x label Mar 14, 2022
Comment on lines 84 to 89
// Binary compatibility hack
F match {
case ce: ConcurrentEffect[F] =>
Http4sServlet.renderResponseContinually(response, servletResponse, bodyWriter)(ce)
case _ => renderResponseDiscontinually(response, servletResponse, bodyWriter)
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh oh.

@armanbilge
Copy link
Member Author

armanbilge commented Mar 14, 2022

The servlet merge is badly botched 😕 would appreciate some help with that one.

Edit: I guess those changes are from #6027 and #6028, does any of that apply to 0.23?

@armanbilge
Copy link
Member Author

Also we should merge #6129 first.

// This F.attempt.flatMap can be interrupted, which prevents the body from
// running, which prevents the response from finalizing. Woe betide you if
// your effect isn't Concurrent.
F.uncancelable { poll =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a crude port of the F.continual, but I think not exactly what we want. We don't want to make bodyWriter or response.body.drain uncancelable. We want to ensure that the response.body finalizer runs if we acquired a response. This ugliness is what we eventually hope to resolve by making responses resourceful.

This needs to be the same logic in blaze and ember.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can poll on on the bodyWriter and the left expression, too. But that's still not exactly correct: we need to finalize the stream, but the finalizer only runs if the stream compilation gets a chance to start.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we can make this program complete and print true, we can plug the leak.

    Ref[IO].of(false).flatMap { ref =>
      val s = Stream.never.onFinalize(ref.set(true))
      IO.uncancelable { poll =>
        IO.canceled *> ???
      }.guarantee(ref.get.flatMap(IO.println(_)))
    }

Copy link
Contributor

@djspiewak djspiewak Mar 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you need poll around bodyWriter(response) and response.body.drain..... I also think you probably want to toss an onCancel on your polls.

we need to finalize the stream, but the finalizer only runs if the stream compilation gets a chance to start

Why can't you rely on onCancel on the poll wrapping the stream compilation?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, polling bodyWriter and response.body.drain seems necessary. But what would onCancel do? response.body.drain perhaps, but what if bodyWriter got interrupted partway through, and response.body's effects are not idempotent?

Again, this is all caused by an unfortunate design choice from before we had Resource. But it's what we have in 0.23, and it affects every backend.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's also why we can't do something like:

Stream.bracket(acquireResponse)(_.body.drain.compile).flatMap(renderResponse)

We can make this as leakproof as 0.22 is and move on, but since we hit merge conflicts, it does seem like a nice opportunity to fix it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is challenging because there isn't a strict separation of acquire-emit-release. There are nested scopes. We might "finalize a response" by calling onFinalize on the body, and then in a middleware wrap more effects. The only way to release all resources acquired for the response but finalized in its body is to uncancelably drain the entire body. Gross!

The right solution is still a resource of a response. Something that could work in 0.23 would be a vault attribute that contains a finalizer. Then a response would look much like a Resource.Allocated and be treated as such. But it would be contrary to how we've told people to finalize resources since dinosaurs roamed the earth.

In any case, I don't think we can solve it the way I envisioned, nor should solve it in this merge.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot to think about. But yeah, would be good to get this merge done, fix the website, and unblock the release train :)

Copy link
Member

@rossabaker rossabaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am intentionally not merging from 0.22. There'll be another train soon enough.

@armanbilge
Copy link
Member Author

I'll do the merge into main, in a little bit.

@armanbilge armanbilge merged commit cd3acf2 into http4s:series/0.23 Mar 18, 2022
rossabaker pushed a commit to http4s/http4s-servlet that referenced this pull request Apr 3, 2022
rossabaker pushed a commit to http4s/http4s-servlet that referenced this pull request Apr 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
behind-the-scenes Appreciated, but not user-facing docs Relates to our website or tutorials module:async-http-client module:servlet series/0.23 PRs targeting 0.23.x
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants