Last active
March 13, 2019 00:30
-
-
Save afsalthaj/8ef6a4fe2a0c1ad2e9beedd459c0df15 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// http://degoes.net/articles/zio-challenge | |
// This is a quick try with Ref and I will keep trying! | |
import scalaz.zio.{UIO, ZIO, _} | |
final case class Percentage(value: Double) extends AnyVal | |
/** | |
* A `Tap` adjusts the flow of tasks through | |
* an external service in response to observed | |
* failures in the service, always trying to | |
* maximize flow while attempting to meet the | |
* user-defined upper bound on failures. | |
*/ | |
trait Tap[-E1, +E2] { | |
/** | |
* Sends the task through the tap. The | |
* returned task may fail immediately with a | |
* default error depending on the service | |
* being guarded by the tap. | |
*/ | |
def apply[R, E >: E2 <: E1, A](effect: ZIO[R, E, A]): ZIO[R, E, A] | |
} | |
object Tap { | |
/** | |
* Creates a tap that aims for the specified | |
* maximum error rate, using the specified | |
* function to qualify errors (unqualified | |
* errors are not treated as failures for | |
* purposes of the tap), and the specified | |
* default error used for rejecting tasks | |
* submitted to the tap. | |
*/ | |
def make[E1, E2]( | |
errBound: Percentage, | |
qualified: E1 => Boolean, | |
rejected: => E2 | |
): UIO[Tap[E1, E2]] = | |
// or Queue ?? | |
Ref.make[List[Boolean]](Nil).map(r => | |
new Tap[E1, E2] { | |
override def apply[R, E >: E2 <: E1, A](effect: ZIO[R, E, A]): ZIO[R, E, A] = | |
for { | |
v <- r.get | |
a <- | |
if (v.count(!_) <= errBound.value * v.size) { | |
effect | |
.either | |
.flatMap( | |
_.fold( | |
e => r.update(addToList(qualified(e))).map(_ => Left[E, A](e)), | |
a => r.update(addToList(true)).map(_ => Right[E, A](a)) | |
) | |
).absolve | |
} else { | |
r.update(addToList(true)) *> ZIO.fail(rejected) | |
} | |
} yield a | |
}) | |
private def addToList[A](a: A): List[A] => List[A] = | |
a :: _.take(10) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When we do;
that would mean, if all of them fails it does make > errorPercentage all of a sudden. However it starts rejecting and make the ratio back on track in future (for new requests)