## Where communities thrive

• Join over 1.5M+ people
• Join over 100K+ communities
• Free without limits
##### Activity
Christopher Davenport
@ChristopherDavenport
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
def liftKleisli[F[_]: Bracket[*[_], Throwable]: cats.Defer, A](client: Client[F]): 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))
}
}
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
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.
Anton Solovyev
@Rosteelton
Yes, but I would like to wrap all endpoints that this client will call.
Ryan Zeigler
@rzeigler
So spans are produced in their own resource. You might have to work directly in Kleisli to extract the span and produce a child span directly inside that resource.
Christopher Davenport
@ChristopherDavenport
I built a middleware specifically for that in http4s.