Skip to content

Instantly share code, notes, and snippets.

View igor-ramazanov's full-sized avatar

Igor Ramazanov igor-ramazanov

View GitHub Profile
@jvican
jvican / RuntimeUtils.scala
Last active November 22, 2019 16:14
Some Scala code that uses Java APIs present in tools.jar (only JDKs) to programmatically produce a jstack-like thread dump. Useful to debug application and test deadlocks.
object RuntimeUtils {
def requestThreadDump: String = {
// Get the PID of the current JVM process
val selfName = java.lang.management.ManagementFactory.getRuntimeMXBean().getName()
val selfPid = selfName.substring(0, selfName.indexOf('@'))
// Attach to the VM
import com.sun.tools.attach.VirtualMachine
import sun.tools.attach.HotSpotVirtualMachine;
val vm = VirtualMachine.attach(selfPid);

Tracing Spec

Tracing is about tracing the structure of an IO computation. Basically, giving some insight into the graph formed by the IO. Tracing is accumulated as the graph is constructed (e.g. by instantiating an IO.Bind node) and reified at the following points:

  • Whenever requested by backtrace: IO[Trace] or printBacktrace: IO[Unit]
  • Whenever an error case is instantiated (IO.Error)

Whenever an exception is rethrown by the interpreter (most commonly in unsafeRunSync()), the associated trace information for that exception should be put into a TracedException wrapper (with cause = the original exception) and that exception should be thrown. This allows backtrace information to participate in side-effectful error recovery and reporting mechanisms. We should consider whether or not we want to also do this with unsafeRunAsync. I'm leaning toward "yes". We should not wrap in TracedException on attempt, raiseError, or any of the other pure error reification mechanisms.

@jdegoes
jdegoes / zio-test.scala
Last active January 6, 2023 14:08
Simple example of testing with ZIO environment
object test {
import scalaz.zio._
type UserID = String
case class UserProfile(name: String)
// The database module:
trait Database {
val database: Database.Service

Thread Pools

Thread pools on the JVM should usually be divided into the following three categories:

  1. CPU-bound
  2. Blocking IO
  3. Non-blocking IO polling

Each of these categories has a different optimal configuration and usage pattern.

Explaining Miles's Magic

Miles Sabin recently opened a pull request fixing the infamous SI-2712. First off, this is remarkable and, if merged, will make everyone's life enormously easier. This is a bug that a lot of people hit often without even realizing it, and they just assume that either they did something wrong or the compiler is broken in some weird way. It is especially common for users of scalaz or cats.

But that's not what I wanted to write about. What I want to write about is the exact semantics of Miles's fix, because it does impose some very specific assumptions about the way that type constructors work, and understanding those assumptions is the key to getting the most of it his fix.

For starters, here is the sort of thing that SI-2712 affects:

def foo[F[_], A](fa: F[A]): String = fa.toString