Skip to content

Instantly share code, notes, and snippets.

View djspiewak's full-sized avatar

Daniel Spiewak djspiewak

View GitHub Profile

Understanding Comparative Benchmarks

I'm going to do something that I don't normally do, which is to say I'm going to talk about comparative benchmarks. In general, I try to confine performance discussion to absolute metrics as much as possible, or comparisons to other well-defined neutral reference points. This is precisely why Cats Effect's readme mentions a comparison to a fixed thread pool, rather doing comparisons with other asynchronous runtimes like Akka or ZIO. Comparisons in general devolve very quickly into emotional marketing.

But, just once, today we're going to talk about the emotional marketing. In particular, we're going to look at Cats Effect 3 and ZIO 2. Now, for context, as of this writing ZIO 2 has released their first milestone; they have not released a final 2.0 version. This implies straight off the bat that we're comparing apples to oranges a bit, since Cats Effect 3 has been out and in production for months. However, there has been a post going around which cites various compar

Summary:
Total: 9.4541 secs
Slowest: 6.4380 secs
Fastest: 0.2701 secs
Average: 4.2429 secs
Requests/sec: 21.1547
Response time histogram:
0.270 [1] |■
diff --git a/examples/ember/src/main/scala/com/example/http4s/ember/EmberServerSimpleExample.scala b/examples/ember/src/main/scala/com/example/http4s/ember/EmberServerSimpleExample.scala
index e103ff09171..44e3c02a48c 100644
--- a/examples/ember/src/main/scala/com/example/http4s/ember/EmberServerSimpleExample.scala
+++ b/examples/ember/src/main/scala/com/example/http4s/ember/EmberServerSimpleExample.scala
@@ -61,6 +61,24 @@ object EmberServerSimpleExample extends IOApp {
Ok(Json.obj("root" -> Json.fromString("GET")))
case GET -> Root / "hello" / name =>
Ok(show"Hi $name!")
+ case req @ POST -> Root / "wut" =>
+ Ok {
/*
* Copyright 2020-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
diff --git a/core/shared/src/main/scala/cats/effect/IOFiber.scala b/core/shared/src/main/scala/cats/effect/IOFiber.scala
index ea00de579..0af2fde00 100644
--- a/core/shared/src/main/scala/cats/effect/IOFiber.scala
+++ b/core/shared/src/main/scala/cats/effect/IOFiber.scala
@@ -26,7 +26,7 @@ import scala.concurrent.duration._
import scala.util.control.NonFatal
import java.util.concurrent.RejectedExecutionException
-import java.util.concurrent.atomic.AtomicBoolean
+import java.util.concurrent.atomic.{AtomicBoolean, AtomicInteger}
/*
* Copyright 2020-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
[info] [Use -Dgraal.LogFile=<path> to redirect Graal log output to a file.]
[info] org.graalvm.libgraal.jni.JNIExceptionWrapper: java.lang.NullPointerException
[info] at org.graalvm.compiler.hotspot.management.Factory.unregister(Factory.java:133)
[info] at org.graalvm.compiler.hotspot.management.JMXFromLibGraalEntryPoints.unregister(JMXFromLibGraalEntryPoints.java:66)
[info] at org.graalvm.libgraal.jni.FromLibGraalCalls.callVoid(FromLibGraalCalls.java:118)
[info] at org.graalvm.compiler.hotspot.management.libgraal.MBeanProxyGen.callUnregister(MBeanProxyGen.java:36)
[info] at org.graalvm.compiler.hotspot.management.libgraal.MBeanProxy.unregister(MBeanProxy.java:425)
[info] at org.graalvm.compiler.hotspot.management.libgraal.MBeanProxy.access$200(MBeanProxy.java:73)
[info] at org.graalvm.compiler.hotspot.management.libgraal.MBeanProxy$OnShutDown.run(MBeanProxy.java:466)
[info] at org.graalvm.compiler.hotspot.HotSpotGraalRuntime.shutdown(HotSpotGraalRuntime.java:512)
#!/bin/bash
set -e
OWNER=$1
REPO=$2
# get the list of projects from the rest API; it's just a pain due to pagination
# curl https://bintray.com/api/v1/repos/$OWNER/$REPO/packages | jq -r .[].name
/*
* Copyright 2020 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

A Study in Multi-Point Deadlocks

Deadlocks are extremely difficult to reason about sometimes. We are used to thinking about them in terms of contention over shared resources, with the pair of exclusive locks being a good and relatively canonical example of this phenomenon. However, sometimes you can find yourself in deadlock scenarios which are caused not so much by an improper sequencing of exclusivity, but rather by insufficient buffer capacity!

These kinds of scenarios are a lot rarer and much more difficult to diagnose and describe, which is why I found this particular puzzle so incredibly fascinating. The following is a screenshot from Cities Skylines (I added textual markers and arrows to make things easier to follow). All vehicles pictured are stationary and unable to move, indefinitely:

Do you see the deadlock? It took me a bit to understand it, but this situation can and does arise in software resource contention where it is dramatically harder to conc