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
Port blaze-core to cats-effect-3 #3894
Conversation
blaze-core/src/main/scala/org/http4s/blazecore/Http1Stage.scala
Outdated
Show resolved
Hide resolved
blaze-core/src/main/scala/org/http4s/blazecore/util/ChunkWriter.scala
Outdated
Show resolved
Hide resolved
blaze-core/src/main/scala/org/http4s/blazecore/util/package.scala
Outdated
Show resolved
Hide resolved
import scala.concurrent.duration.{Duration, _} | ||
|
||
/** | ||
* copy of [[cats.effect.testing.specs2.CatsEffect]] adapted to cats-effect 3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need a migrated https://github.com/djspiewak/cats-effect-testing.
blaze-core/src/test/scala/org/http4s/blazecore/util/Http1WriterSpec.scala
Outdated
Show resolved
Hide resolved
blaze-core/src/test/scala/org/http4s/blazecore/util/Http1WriterSpec.scala
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really not an expert in blaze, but left some comments here and there
blaze-core/src/main/scala/org/http4s/blazecore/Http1Stage.scala
Outdated
Show resolved
Hide resolved
blaze-core/src/main/scala/org/http4s/blazecore/util/ChunkWriter.scala
Outdated
Show resolved
Hide resolved
blaze-core/src/main/scala/org/http4s/blazecore/util/package.scala
Outdated
Show resolved
Hide resolved
Thanks for the feedback @SystemFw ! |
blaze-core/src/main/scala/org/http4s/blazecore/util/Http2Writer.scala
Outdated
Show resolved
Hide resolved
|
||
import scala.concurrent.duration.{Duration, _} | ||
|
||
/** copy of [[cats.effect.testing.specs2.CatsEffect]] adapted to cats-effect 3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be a good issue on the cats-effect-testing repo.
Until then, I think we could put it in our testing package and maybe use it in multiple modules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
blaze-core/src/test/scala/org/http4s/blazecore/util/Http1WriterSpec.scala
Outdated
Show resolved
Hide resolved
blaze-core/src/test/scala/org/http4s/blazecore/util/Http1WriterSpec.scala
Outdated
Show resolved
Hide resolved
7ff51be
to
9257737
Compare
The compilation of the 2 specs seems to wait for the same lock. The compilation never completes. ``` | => org.http4s.blazecore.util.Http1WriterSpec 63s | => org.http4s.blazecore.websocket.Http4sWSStageSpec 63s ```
I'm now blocked by the running of the tests: e9eeb95 The 2 specs seems to wait for the same lock. The tests never complete. |
Update: the issue seems to be only on |
@@ -152,25 +153,26 @@ private[http4s] class Http4sWSStage[F[_]]( | |||
.compile | |||
.drain | |||
|
|||
unsafeRunAsync(wsStream) { | |||
val result = F.attempt(wsStream).flatMap { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Current situation: F.attempt(wsStream)
does not make any progress.
In the previous implementation (unsafeRunAsync(wsStream)
), wsStream
was "shift" to the execution context provided in the constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm very far out of the CE3 loop right now. Do we need a start
or something similar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Dispatcher
can start it. See at line 165: D.unsafeRunSync(result)
.
When I add a timeout at this line, the timeout exception is coming from this place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unsafeRunSync
is blocking, so the semantics have changed here. Try unsafeToFuture
instead of unsafeRunSync
, or add .start
at the end of result
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also the attempt
can become an handleErrorWith
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still have questions about the .unsafeRunSync(), if this waits for the start.
it waits for the completion of the portion of IO preceding the first async boundary. In this case, because there is a shift
immediately, it essentially doesn't wait. (and this is in CE2 anyway)
If yes unsafeRunAsync starts the side-effect on another thread pool right?
Strictly speaking (in CE2), it just follows what the IO does, and will follow whatever async boundary the IO has. In this case there is an immediate shift. In CE3 the model is conceptually simpler.
As unsafeToFuture returns a Future, should we wait for the Future with an Await.result or something similar?
no, we don't need to Await.result
, and in fact what you're doing right now with unsafeRunSync
is essentially Await.result
, which I think it's causing the deadlock in the test.
then we can start the Future and ignore it, just returning Unit.
yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact, call unsafeRunAndForget
on Dispatcher
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SystemFw thank you a lot for your detailed answers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for porting this :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
current status: all tests are now running. @rossabaker this PR is quite messy as it contains a lot of commits. |
The decision is definitely for Ross, but I actually really dislike that. The history is valuable, if you have ever have to run a bisect on a tough bug, big commits are a pain. In any case, if you do want to do that, there's no need to open a new PR, you can squash on merge (but don't ;)) |
I agree with @SystemFw. It also makes it harder to re-review things: we have to look at the whole instead of the recent changes. I usually never force-push a PR unless I don't think anybody has looked at it yet and I think I can tell a better story with a The more controversial thing is whether we should squash at merge time or not. Squash merges make a cleaner history and we can still click through to see the original intermediate commits. But even then, I think the intermediate commits have value. In addition to bisection, sometimes we branch off WIP to explore a different direction or, like now, maintain parallel branches through big upgrades. Squashing is better for history but worse for collaboration, and we've optimize for the latter. All that said, I'm excited to see the progress, but it's 1:30am here, so I'll have to review it tomorrow. Hopefully our CE3 experts can keep looking as well. |
There is one topic I'm feeling unsure about: I had to create one dispatcher per test in But I can still share a dispatcher in And this is a change I could eventually rollback: c59e3be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is multiple dispatchers a normal usage? I'm a bit worried that having to do that is masking an issue that will prevent the web sockets from working in the real world, but my understanding of CE3 is still a bit hazy.
I like the way the rest of this has shaped up.
|
||
/** copy of [cats.effect.testing.specs2.CatsEffect](https://github.com/djspiewak/cats-effect-testing/blob/series%2F0.x/specs2/src/main/scala/cats/effect/testing/specs2/CatsEffect.scala) adapted to cats-effect 3 | ||
*/ | ||
trait CatsEffect { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Has this been contributed upstream? This is fine for now, but it would be good for this to not be ours.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This reverts commit f7d5840.
Thanks to the help from @djspiewak, I could remove blocking calls: ce3ea53 Now all the tests can run with the same For the curious, this is the kind of stack trace I could find by inspecting the threads:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was just that unsafeRunSync to create that semaphore in the stage? In CE2, that's a "I promise not to share this" thing. I wouldn't expect it to deadlock things. The Dispatcher
is a different world, though.
Anyway, hooray, and great job.
Yes, the
Thanks, that was a long way. |
Port blaze-core to cats-effect-3
#3837
It's a WIP.
I'd like to receive some early feedback before attacking the websocket part.