Skip to content

Commit

Permalink
Add FeatureClient After hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcardell committed Sep 13, 2024
1 parent c906658 commit 0728704
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ trait FeatureClient[F[_]] {
def evaluationContext: EvaluationContext
def withEvaluationContext(context: EvaluationContext): FeatureClient[F]

def beforeHooks: List[BeforeHook[F]]

def withHook(hook: Hook[F]): FeatureClient[F]
// def withHooks(hooks: List[Hook]): FeatureClient[F]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ protected[openfeature] final class FeatureClientImpl[F[_]](
provider: EvaluationProvider[F],
val clientEvaluationContext: EvaluationContext,
val beforeHooks: List[BeforeHook[F]],
val errorHooks: List[ErrorHook[F]]
val errorHooks: List[ErrorHook[F]],
val afterHooks: List[AfterHook[F]]
)(implicit M: MonadThrow[F])
extends FeatureClient[F] {

Expand All @@ -42,7 +43,8 @@ protected[openfeature] final class FeatureClientImpl[F[_]](
provider,
clientEvaluationContext ++ context,
beforeHooks,
errorHooks
errorHooks,
afterHooks
)

override def withHook(hook: Hook[F]): FeatureClient[F] =
Expand All @@ -52,16 +54,25 @@ protected[openfeature] final class FeatureClientImpl[F[_]](
provider,
clientEvaluationContext,
beforeHooks.appended(h),
errorHooks
errorHooks,
afterHooks
)
case h: ErrorHook[F] =>
new FeatureClientImpl[F](
provider,
clientEvaluationContext,
beforeHooks,
errorHooks.appended(h)
errorHooks.appended(h),
afterHooks
)
case h: AfterHook[F] =>
new FeatureClientImpl[F](
provider,
clientEvaluationContext,
beforeHooks,
errorHooks,
afterHooks.appended(h)
)
case _ => ???
}

override def getBooleanValue(flagKey: String, default: Boolean): F[Boolean] =
Expand Down Expand Up @@ -361,11 +372,16 @@ protected[openfeature] final class FeatureClientImpl[F[_]](
for {
newContext <- Hooks.runBefore[F](beforeHooks)(hookContext, hookHints)
evaluation <- evaluate(newContext)
_ <-
Hooks.runAfter[F](afterHooks)(
hookContext.copy(evaluationContext = newContext),
hookHints
)
} yield evaluation

run
.onError { case e =>
Hooks.runErrors(errorHooks)(hookContext, hookHints, e)
.onError { case error =>
Hooks.runErrors(errorHooks)(hookContext, hookHints, error)
}
.handleError(error =>
EvaluationDetails(flagKey, ResolutionDetails.error(default, error))
Expand All @@ -384,7 +400,8 @@ object FeatureClientImpl {
provider = provider,
clientEvaluationContext = EvaluationContext.empty,
beforeHooks = List.empty[BeforeHook[F]],
errorHooks = List.empty[ErrorHook[F]]
errorHooks = List.empty[ErrorHook[F]],
afterHooks = List.empty[AfterHook[F]]
)

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package io.cardell.openfeature

import cats.Applicative
import cats.Monad
import cats.syntax.all._

Expand All @@ -24,7 +25,6 @@ import io.cardell.openfeature.FlagValue.DoubleValue
import io.cardell.openfeature.FlagValue.IntValue
import io.cardell.openfeature.FlagValue.StringValue
import io.cardell.openfeature.FlagValue.StructureValue
import cats.Applicative

sealed trait FlagValueType

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import io.cardell.openfeature.ErrorHook
import io.cardell.openfeature.Hook

trait Provider[F[_]] extends EvaluationProvider[F] {
// TODO remove
def beforeHooks: List[BeforeHook[F]]
def errorHooks: List[ErrorHook[F]]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ package io.cardell.openfeature.provider
import cats.MonadThrow
import cats.syntax.all._

import io.cardell.openfeature.AfterHook
import io.cardell.openfeature.BeforeHook
import io.cardell.openfeature.ErrorHook
import io.cardell.openfeature.AfterHook
import io.cardell.openfeature.EvaluationContext
import io.cardell.openfeature.FlagValue
import io.cardell.openfeature.Hook
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ class FeatureClientImplTest extends CatsEffectSuite {

val client = FeatureClientImpl[IO](provider)

val result = client.withHook(beforeHook1).beforeHooks
val result =
client
.withHook(beforeHook1)
.asInstanceOf[FeatureClientImpl[IO]]
.beforeHooks

assertEquals(expected, result)
}
Expand Down Expand Up @@ -114,6 +118,21 @@ class FeatureClientImplTest extends CatsEffectSuite {
}
}

test("before hooks run on boolean evaluation") {
val ref = Ref.unsafe[IO, Int](0)

val afterHook = AfterHook[IO] { case _ => ref.update(_ + 2) }

val client = FeatureClientImpl[IO](provider).withHook(afterHook)

val expected = 2

for {
_ <- client.getBooleanValue("test-flag", false)
result <- ref.get
} yield assertEquals(result, expected)
}

}

object ThrowingEvaluationProvider extends EvaluationProvider[IO] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import cats.effect.IO
import cats.effect.kernel.Ref
import munit.CatsEffectSuite

import io.cardell.openfeature.AfterHook
import io.cardell.openfeature.BeforeHook
import io.cardell.openfeature.ErrorHook
import io.cardell.openfeature.AfterHook
import io.cardell.openfeature.EvaluationContext
import io.cardell.openfeature.HookContext
import io.cardell.openfeature.HookHints
Expand Down

0 comments on commit 0728704

Please sign in to comment.