Skip to content

Instantly share code, notes, and snippets.

View vkostyukov's full-sized avatar

Vladimir Kostyukov vkostyukov

View GitHub Profile
vkostyukov / bug.scala
Created March 17, 2023 05:13
Armeria Bug
test("requestLog never completed with empty streaming response") {
val closed = new AtomicBoolean(false)
val service = new HttpService {
override def serve(ctx: ServiceRequestContext, req: HttpRequest): HttpResponse = {
val rep = HttpResponse.streaming()
vkostyukov / IOTwitterServer.scala
Last active February 12, 2020 17:00
import cats.effect.{ContextShift, IO, Resource, Timer}
import com.twitter.finagle.{Http, ListeningServer, Service}
import com.twitter.finagle.http.{Request, Response}
import com.twitter.server.TwitterServer
import com.twitter.util.Future
import io.finch.Endpoint
import io.finch.internal.ToEffect
import java.util.concurrent.CountDownLatch
import scala.concurrent.ExecutionContext
vkostyukov /
Created August 21, 2017 21:44
public interface com.twitter.finagle.stats.StatsReceiver {
public static com.twitter.finagle.stats.Counter counter$(com.twitter.finagle.stats.StatsReceiver, java.lang.String...);
public com.twitter.finagle.stats.Counter counter(java.lang.String...);
public static com.twitter.finagle.stats.Counter counter$(com.twitter.finagle.stats.StatsReceiver, com.twitter.finagle.stats.Verbosity, java.lang.String...);
public com.twitter.finagle.stats.Counter counter(com.twitter.finagle.stats.Verbosity, java.lang.String...);
public static com.twitter.finagle.stats.Stat stat$(com.twitter.finagle.stats.StatsReceiver, java.lang.String...);
public com.twitter.finagle.stats.Stat stat(java.lang.String...);
public static com.twitter.finagle.stats.Stat stat$(com.twitter.finagle.stats.StatsReceiver, com.twitter.finagle.stats.Verbosity, java.lang.String...);
public com.twitter.finagle.stats.Stat stat(com.twitter.finagle.stats.Verbosity, java.lang.String...);
public static com.twitter.finagle.stats.Gauge addGauge$(com
vkostyukov /
Last active July 19, 2018 16:39
Finch: A Life Without Exceptions

Finch: A Life Without Exceptions

Historically, Finch's error handling machinery was built on a very simple yet silly idea that an Endpoint may return a failed Future (i.e., Future.exception). While that doesn't really promote a purely functional approach to error handling (i.e., treat errors as values), it enables quite a few handy setups, including:

  • embedding 3rd-party Finagle clients (that may fail) within endpoints w/o extra boilerplate
  • simple/minimal required endpoints (i.e., body, param, etc) that return A, not Try[A] nor Either[Error, A]

However this part of Finch's design was heavily influenced by Finagle itself (w.r.t. embedding all of its failures in Future.exception), nothing stops us from revisiting this trade-off and possibly discussing paths forward more idiomatic error handling.

Implicit Errors vs. Explicit Errors

vkostyukov / AccessLog.scala
Created February 10, 2017 18:27
AccessLog for Finagle
import java.util.concurrent.Executors
import{File, FileOutputStream, PrintWriter}
import com.twitter.finagle.{Service, SimpleFilter}
import com.twitter.finagle.http.{Request, Response}
import com.twitter.util.Future
final class AccessLog(file: File) extends SimpleFilter[Request, Response] {
private[this] final val scheduler = Executors.newSingleThreadExecutor()
vkostyukov / adts.scala
Last active January 30, 2017 23:59
Java-friendly ADTs in Scala
// In Scala
sealed abstract class Toggle
object Toggle {
private case object ON extends Toggle
private case object OFF extends Toggle
def On: Toggle = ON
def Off: Toggle = OFF
vkostyukov / currentTime.scala
Last active January 25, 2017 21:14
Fast currentTime in seconds
import java.time.format.DateTimeFormatter
import java.time.{Instant, ZoneOffset}
object currentTime {
private[this] val formatter: DateTimeFormatter =
@volatile private[this] var last: (Long, String) = (0, "")
def apply(): String = {
vkostyukov /
Last active December 25, 2016 03:10
EndpointResult Bechmark


[info] Benchmark                                                       Mode  Cnt     Score      Error   Units
[info] BodyBenchmark.byteArray                                         avgt    6   876.637 ±   84.132   ns/op
[info] BodyBenchmark.byteArray:·gc.alloc.rate.norm                     avgt    6  1968.001 ±   49.149    B/op
[info] BodyBenchmark.byteArray                                         avgt    6   788.304 ±   60.485   ns/op
[info] BodyBenchmark.byteArray:·gc.alloc.rate.norm                     avgt    6  1912.001 ±    0.001    B/op
vkostyukov / finch-dispatch.scala
Created September 26, 2016 20:08
Dispatch on a case
import io.finch._
sealed trait Req
object Req {
case class Foo(i: Int) extends Req
case class Bar(s: String) extends Req
def dispatch[A](pf: PartialFunction[Req, Output[A]]): Endpoint[A] = new Endpoint[A] {
override def apply(i: Input): Endpoint.Result[A] =[Req].apply(i).flatMap {
vkostyukov /
Last active March 15, 2016 16:57

Pairs: Before and After

[info] Benchmark                                                    Mode  Cnt     Score     Error   Units
[info] BodyBenchmark.byteArray                                      avgt   12   622.368 ±  48.389   ns/op
[info] BodyBenchmark.byteArray:·gc.alloc.rate.norm                  avgt   12  1856.000 ±  42.810    B/op

[info] BodyBenchmark.byteArray                                      avgt   12   746.891 ±  67.571   ns/op
[info] BodyBenchmark.byteArray:·gc.alloc.rate.norm                  avgt   12  1916.000 ±   5.351    B/op