## Where communities thrive

• Join over 1.5M+ people
• Join over 100K+ communities
• Free without limits
• Create your own community
##### Activity
Tristan Lohman
@gatorcse
k, I’ll see if I can reproduce it in a minimal example tonight
I literally just switched from blaze to ember in my app harness, app hung on all outgoing requests, and switched back, I have no other info than that.
Christopher Davenport
@ChristopherDavenport
As far as the client. It requires the span and then you translate to kleisli. Then you apply the base span for the stream transformation. I have this in an example but I need to rip out the proprietary stuff tomorrow.
Christopher Davenport
@ChristopherDavenport
Alright, I threw it together again
def liftKleisli[F[_]: Bracket[*[_], Throwable]: cats.Defer, A](
client: Client[F],
a: A
): Client[Kleisli[F, A, *]] = Client{
req: Request[Kleisli[F, A, *]] =>
val newReq = req.mapK(Kleisli.applyK(a))
client.run(newReq)
.mapK(Kleisli.liftK[F, A])
.map(_.mapK(Kleisli.liftK))
}
So you can get it there via extracting the span and then using that function
liftKleisli(blazeClient, baseSpan)
You can also just extract it using the algebra
Scratch that, use this
Christopher Davenport
@ChristopherDavenport
def liftKleisli[F[_]: Bracket[*[_], Throwable]: cats.Defer, A](client: Client[F]): Client[Kleisli[F, A, *]] =
Client{ req: Request[Kleisli[F, A, *]] =>
Resource.liftF(Kleisli.ask[F, A]).flatMap{ a =>
val newReq = req.mapK(Kleisli.applyK(a))
client.run(newReq)
.mapK(Kleisli.liftK[F, A])
.map(_.mapK(Kleisli.liftK))
}
}
Timothy Bess
@tdbgamer
Wow that's gonna take me a second to digest, thanks for whipping it up so fast, really appreciate it. I'll test it out
Christopher Davenport
@ChristopherDavenport
http4s/http4s#3552 - I also created a PR to http4s to hopefully get this easier out of the box.
Timothy Bess
@tdbgamer
Dude! you're the greatest, thanks so much.
wow talk about going above and beyond
this also solved my issue with having the root created at the wrong level
Christopher Davenport
@ChristopherDavenport
This is what OSS is all about. :+1:
Tristan Lohman
@gatorcse
@ChristopherDavenport oh, that looks like exactly what I needed. I was getting too crazy trying to translate straight from F to G, your way just using all the mapK’s and liftK’s looks way better
just
Tristan Lohman
@gatorcse
@ChristopherDavenport Hey, finally got a minimal example. Normally the ember client is fine, the problem actually only crops up when using with the natchez Kleisli.
Example incoming
Sorry, it hangs when using the natchez kleisli and the response is more than one chunk.
Scala 2.13, http4s 0.21.6, natchez 0.0.11
Tristan Lohman
@gatorcse
Thanks, any help would be greatly appreciated!
Actually should this be a bug report? And in http4s or in natchez?
Christopher Davenport
@ChristopherDavenport
Http4s is probably the appropriate place for that bug report please. I just fixed chunked so I find that suprising but perhaps I can figure it out from that.
Stephen Bly
@sbly
Hello @tpolecat! Thank you for this project, it's very helpful. Is there any chance you could review my PR tpolecat/natchez#145 when you get the chance? I also have a few more I'm planning to make.
Rob Norris
@tpolecat
Yep, I have it in a tab. I'll try to get to it tomorrow.
Stephen Bly
@sbly
Thank you!
Ryan Zeigler
@rzeigler
Question about the trait Fields. Is this meant to be automatically handled by natchez? I thought it seemed like it might be something that was, however, I went reading and couldn't find anything in the source code that consumes it.
It's probably possible to generalize this.
The specific behaviors under error conditions are all implementation-dependent right now.
Ryan Zeigler
@rzeigler
The kleisli trace already requires a bracket instance. Would it make sense to just do it there?
Rob Norris
@tpolecat
Possibly.
Ryan Zeigler
@rzeigler
Would you accept a PR to that effect?
Rob Norris
@tpolecat
Well it shouldn't require a trace effect. You should be able to do this with a raw Span.
Ryan Zeigler
@rzeigler
Possibly something that lifts a Resource[F, Span[F]] to a Resource[F, Span[F]] + Fields tracking then?
and then the individual drivers can make use
Jente Hidskes
@Hjdskes
Hey folks! Is there a slightly more involved piece of code that I can study somewhere that uses Natchez? I'm particularly struggling to integrate this into my existing codebase which is structured after Gabriel Volpe's book (https://github.com/gvolpe/pfps-shopping-cart). Because the algebras and interpreters are all created before requests start coming in, I can't (as far as I know at least) simply put a Trace[F] in the context bound for those and call it a day.
Anton Solovyev
@Rosteelton

Hi! Need some help with wiring with natchez.
I have one big wire function:

  def wireAll[F[_]: ContextShift: Timer: Parallel: Concurrent: Async]: Resource[F, HttpRoutes[F]]

And one run function:

def run[F[_]: ContextShift: ConcurrentEffect: Timer: Parallel: Bracket[*[_], Throwable]]: F[Fiber[F, Unit]] = {
val resource =  for {
traceEntryPoint <- entryPoint[F]: Resource[F, EntryPoint[F]]
httpRoutes <- wireAll[Kleisli[F, Span[F], *]]: Resource[Kleisli[F, Span[F], *], HttpRoutes[Kleisli[F, Span[F], *]]
//after that I can obtain HttpRoutes[F] from HttpRoutes[Kleisli[F, Span[F], *] using middleware and run server
...
} yield ()
...
}

The problem is in the first Resource type parameter - Kleisli[F, Span[F], *] (F needed)
Do you know how to rewrite this correctly?

Jakub Kozłowski
@kubukoz
@Rosteelton I would suggest that you mapK from that resource Resource[Kleisli[F, Span[F], *], HttpRoutes[Kleisli[F, Span[F], *]] to Resource[F, HttpRoutes[Kleisli[F, Span[F], *]]. You'll need a Kleisli[F, Span[F], *] ~> F
which is basically Kleisli.applyK, but you'll still need a Span[F]. You can probably use one that you get from the entrypoint - this will basically be the span of "starting the application"
I'm not sure I explained that well
httpRoutes <- traceEntryPoint.root("init").use { span => wireAll[Kleisli[F, Span[F], *]].mapK(Kleisli.applyK(span)) } - roughly
I didn't compile that though
btw. I wouldn't recommend this shape F[Fiber[F, Unit]], it's easy to make a mistake. See if you can use .background instead of .start wherever it is.
Anton Solovyev
@Rosteelton
@kubukoz Thanks! Helped a lot!
Jakub Kozłowski
@kubukoz
glad :)
Anton Solovyev
@Rosteelton

It's me again. I am trying to wrap Client[F]. (I have Trace[F] instance there)

  def apply[F[_]: Trace: Sync](client: Client[F]): Client[F] = {
Client[F] { request =>
val spanName: String = ???
for {
b <- Trace[F].span(spanName) { //should be F[]
}
//only have Resource[F, Response[F]] type for
//client.run(modifiedRequest))
} yield ???
}
}

Can't get how to transform Resource to wrap it with Trace[F].span

Ryan Zeigler
@rzeigler
You can use the Trace[F].span wherever you use the Response[F] rather than during construction time.