Skip to content

Instantly share code, notes, and snippets.

View calvinlfer's full-sized avatar

Calvin Lee Fernandes calvinlfer

View GitHub Profile
@calvinlfer
calvinlfer / InterruptibleReadLineExample.scala
Created September 27, 2024 20:14
An example of how to achieve an interruptible readLine with ZIO
import zio.*
import scala.Console as SConsole
import scala.io.StdIn
import java.io.{BufferedReader, IOException}
import scala.util.Try
object InterruptibleReadLineExample extends ZIOAppDefault {
def altReadLine(reader: BufferedReader = SConsole.in) =
ZIO
@calvinlfer
calvinlfer / KyoPlayground.scala
Created September 21, 2024 23:26
Modelling lazy infinite streams in Kyo 0.12.x (https://getkyo.io/#/?id=stream-composable-data-processing)
import kyo.*
import kyo.Emit.Ack
object Playground extends KyoApp:
def recursiveStream(start: Int): Stream[Int, IO] =
def go(n: Int): Ack < Emit[Chunk[Int]] =
Emit.andMap(Chunk(n)):
case Ack.Stop => Ack.Stop
case Ack.Continue(_) => go(n + 1)
@calvinlfer
calvinlfer / Avro4sDeserializer.scala
Created June 8, 2024 17:37
FS2 Kafka Avro4S support (Schema Registry aware)
import com.sksamuel.avro4s.{Decoder, SchemaFor}
import fs2.kafka.{Deserializer, ValueDeserializer, KeyDeserializer}
import fs2.kafka.vulcan.AvroSettings
import cats.effect.{Sync, Resource}
import java.nio.ByteBuffer
import io.confluent.kafka.schemaregistry.avro.AvroSchema
final class Avro4sDeserializer[A >: Null](
private val decoder: Decoder[A],
private val schemaFor: SchemaFor[A]
package io.kaizensolutions.virgil.nextlevel
import io.kaizensolutions.virgil.nextlevel.nextlevel.peopleTable
object nextlevel {
sealed trait Table {
type TableTag
}
object Table {
@calvinlfer
calvinlfer / build-native-image.sh
Created May 8, 2023 13:06
ZIO HTTP (Graal Native Image & Scala CLI)
#!/bin/sh
scala-cli --power package --native-image -f *.scala -o ziohttp.bin -- --no-fallback --enable-url-protocols=http,https -Djdk.http.auth.tunneling.disabledSchemes= --install-exit-handlers --enable-http --initialize-at-run-time=io.netty.channel.DefaultFileRegion --initialize-at-run-time=io.netty.channel.epoll.Native --initialize-at-run-time=io.netty.channel.epoll.Epoll --initialize-at-run-time=io.netty.channel.epoll.EpollEventLoop --initialize-at-run-time=io.netty.channel.epoll.EpollEventArray --initialize-at-run-time=io.netty.channel.kqueue.KQueue --initialize-at-run-time=io.netty.channel.kqueue.KQueueEventLoop --initialize-at-run-time=io.netty.channel.kqueue.KQueueEventArray --initialize-at-run-time=io.netty.channel.kqueue.Native --initialize-at-run-time=io.netty.channel.unix.Limits --initialize-at-run-time=io.netty.channel.unix.Errors --initialize-at-run-time=io.netty.channel.unix.IovArray --initialize-at-run-time=io.netty.handler.codec.compression.ZstdOptions --initialize-at-run-time=io.netty.incub
@calvinlfer
calvinlfer / ZioHttpServerTracer.scala
Created February 17, 2023 19:42
getting tracing to work with zio-http 0.0.4's new Handler abstraction
package io.kaizensolutions.trace4cats.zio.extras.ziohttp.server
import trace4cats.ErrorHandler
import trace4cats.model.AttributeValue.{LongValue, StringValue}
import trace4cats.model.SemanticAttributeKeys.*
import trace4cats.model.{AttributeValue, SpanKind, SpanStatus}
import io.kaizensolutions.trace4cats.zio.extras.ZTracer
import io.kaizensolutions.trace4cats.zio.extras.ziohttp.{extractTraceHeaders, toSpanStatus}
import zio.*
import zio.http.*
@calvinlfer
calvinlfer / OneToManyJoin.scala
Created November 25, 2022 17:49
In memory one to many join
def joinLManyR[Err, LeftElem, LeftKey, MiddleElem, MiddleKey, RightElem, RightKey, RightProjection](left: Iterable[LeftKey])(
middle: Iterable[LeftKey] => Stream[Err, MiddleElem]
)(middleKey: MiddleElem => MiddleKey)(middleToLeftKey: MiddleElem => LeftKey)(middleToRightKey: MiddleElem => RightKey)(
right: Iterable[RightKey] => Stream[Err, RightElem]
)(rightKey: RightElem => RightKey)(rightProjection: RightElem => RightProjection): IO[Err, Map[LeftKey, Set[RightProjection]]] =
val extractMiddle: IO[Err, Chunk[MiddleElem]] = middle(left).runCollect
def rightElems(in: Iterable[RightKey]): IO[Err, Chunk[RightElem]] =
right(in).runCollect
@calvinlfer
calvinlfer / ZonedDateTimeRange.scala
Last active October 31, 2022 20:16
Preliminary support for a specific range in Skunk
import skunk.Codec
import skunk.data.Type
import zio.ZIOAppDefault
import java.time.{OffsetDateTime, ZonedDateTime}
import java.time.format.{DateTimeFormatter, DateTimeFormatterBuilder, DateTimeParseException}
import java.time.temporal.ChronoField.*
import java.util.Locale
// TODO: account for closed and open intervals so like [x,y), (x,y), etc.
@calvinlfer
calvinlfer / docker-compose.yaml
Created May 7, 2022 20:21
Single node Kafka docker-compose compatible with Docker on M1 Macs
version: "3.9"
services:
zookeeper:
restart: unless-stopped
image: ubuntu/zookeeper:latest
ports:
- "2181:2181"
kafka:
@calvinlfer
calvinlfer / pipeline.scala
Created May 3, 2022 14:12
Understanding ZChannels (zio-streams 2.x)
object Experiment extends ZIOAppDefault {
/**
Collect elements and emit them in single chunks of 100
*/
val aggregate: ZPipeline[Any, Nothing, Int, Long] = {
def go[Err](acc: Long): ZChannel[Any, Err, Chunk[Int], Any, Err, Chunk[Long], Any] =
ZChannel.readWith[Any, Err, Chunk[Int], Any, Err, Chunk[Long], Any](
in = { inChunk =>
val next = acc + inChunk.sum
if (next > 100L) {