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

Tracing doodles #50

Closed
wants to merge 10 commits into from
Closed
20 changes: 17 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,24 @@ val catsEffectVersion = "3.2.9"
val circeVersion = "0.14.1"
val fs2Version = "3.2.2"
val http4sVersion = "0.23.6"
val natchezVersion = "0.1.5"

lazy val root =
project
.in(file("."))
.aggregate(
core.js,
core.jvm,
lambdaCloudFormationCustomResource.js,
lambdaCloudFormationCustomResource.jvm,
lambda.js,
lambda.jvm,
lambdaEvents.js,
lambdaEvents.jvm,
lambdaNatchez.js,
lambdaNatchez.jvm,
lambdaApiGatewayProxyHttp4s.js,
lambdaApiGatewayProxyHttp4s.jvm
lambdaApiGatewayProxyHttp4s.jvm,
lambdaCloudFormationCustomResource.js,
lambdaCloudFormationCustomResource.jvm
)
.enablePlugins(NoPublishPlugin)

Expand Down Expand Up @@ -98,6 +101,17 @@ lazy val lambdaEvents = crossProject(JSPlatform, JVMPlatform)
)
)

lazy val lambdaNatchez = crossProject(JSPlatform, JVMPlatform)
.crossType(CrossType.Pure)
.in(file("lambda-natchez"))
.settings(
name := "feral-lambda-natchez",
libraryDependencies ++= Seq(
"org.tpolecat" %%% "natchez-core" % natchezVersion
)
)
.dependsOn(lambda, lambdaEvents)

lazy val lambdaApiGatewayProxyHttp4s = crossProject(JSPlatform, JVMPlatform)
.crossType(CrossType.Pure)
.in(file("lambda-api-gateway-proxy-http4s"))
Expand Down
35 changes: 35 additions & 0 deletions lambda-natchez/src/main/scala/feral/lambda/natchez/HasKernel.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2021 Typelevel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package feral.lambda.natchez

import feral.lambda.events.ApiGatewayProxyEventV2
import natchez.Kernel

trait HasKernel[Event] {
def extract(event: Event): Kernel
}

object HasKernel extends HasKernelLowPriority {
@inline def apply[E](implicit hk: HasKernel[E]): hk.type = hk

implicit val apiGateProxyEventV2Kernel: HasKernel[ApiGatewayProxyEventV2] =
e => Kernel(e.headers)
}
Comment on lines +26 to +31
Copy link
Member Author

Choose a reason for hiding this comment

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

One of the nice things about having all the events together in the same module is it makes it easy to provide these implicits. Although I'm doubtful if any will have a special implementation except this one.


private[natchez] sealed class HasKernelLowPriority {
implicit def emptyKernel[E]: HasKernel[E] = _ => Kernel(Map.empty)
}
27 changes: 27 additions & 0 deletions lambda-natchez/src/main/scala/feral/lambda/natchez/LiftTrace.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2021 Typelevel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package feral.lambda.natchez

import cats.~>
import natchez.Span
import natchez.Trace

// https://github.com/tpolecat/natchez/pull/448
trait LiftTrace[F[_], G[_]] {
def run[A](span: Span[F])(f: Trace[G] => G[A]): F[A]
def liftK: F ~> G
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright 2021 Typelevel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package feral.lambda.natchez

import cats.effect.kernel.MonadCancelThrow
import feral.lambda.Lambda
import natchez.EntryPoint
import natchez.Trace

object TracedLambda {
def apply[F[_]: MonadCancelThrow, G[_], Event: HasKernel, Result](entryPoint: EntryPoint[F])(
lambda: Trace[G] => Lambda[G, Event, Result])(
Copy link
Member Author

@armanbilge armanbilge Nov 17, 2021

Choose a reason for hiding this comment

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

I'm not sure yet how I feel about injecting Trace[G] like this. It's a bit awkward, but I think it's a cleaner way to support IOLocal-based tracing, or generally tracing in a generic G.

implicit lift: LiftTrace[F, G]): Lambda[F, Event, Result] = { (event, context) =>
val kernel = HasKernel[Event].extract(event)
entryPoint.continueOrElseRoot(context.functionName, kernel).use { span =>
lift.run(span)(lambda(_)(event, context.mapK(lift.liftK)))
}
}
}
7 changes: 6 additions & 1 deletion lambda/shared/src/main/scala/feral/lambda/Context.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package feral.lambda

import cats.~>

import scala.concurrent.duration.FiniteDuration

final case class Context[F[_]](
Expand All @@ -29,7 +31,10 @@ final case class Context[F[_]](
identity: Option[CognitoIdentity],
clientContext: Option[ClientContext],
remainingTime: F[FiniteDuration]
)
) {
def mapK[G[_]](f: F ~> G): Context[G] =
copy(remainingTime = f(remainingTime))
}

object Context extends ContextCompanionPlatform

Expand Down