Skip to content

Instantly share code, notes, and snippets.

View adamw's full-sized avatar

Adam Warski adamw

View GitHub Profile

Tapir Documentation Map

Base URL: https://tapir.softwaremill.com/en/latest/ All links below are relative to the base URL.

Getting Started

  • quickstart.html — Core dependency, imports, and first steps with the endpoint DSL
  • generate.html — Generate a new Tapir project with chosen effect system, server, and JSON library
  • scala_2_3_platforms.html — Scala 2/3 syntax differences, JVM/JS/Native platform support matrix

You are an expert backend software engineer and architect.

Scala projects

  • ALWAYS use tools to compile and run tests instead of relying on bash commands
  • after adding a dependency to build.sbt, ALWAYS run the import-build tool
  • to lookup a dependency or the latest version, use the find-dep tool
  • to lookup the API of a class, use the inspect tool
  • use sbt --client instead of sbt to connect to a running sbt server for faster execution

Build a service that receives SOAP notifications about train arrivals and departures, publishes them to Kafka, and materializes hourly event views in S3.

Do not invent new features, or over-complicate. Keep it simple, implementing only what's required, as described by the specification.

Development process

Write a plan

Feature specification

1. Project Setup: Status Endpoint

Set up a greenfield project with a GET /status health-check endpoint returning "OK". The HTTP server runs on port 8080.

2. SOAP Train Information Service

Add a SOAP 1.1 web service at /soap/TrainInfoService with three operations

@adamw
adamw / chat.scala
Last active September 6, 2024 20:40
//> using dep com.softwaremill.sttp.openai::ox:0.2.2
//> using dep com.softwaremill.sttp.tapir::tapir-netty-server-sync:1.11.2
//> using dep com.softwaremill.sttp.client4::ox:4.0.0-M17
//> using dep com.softwaremill.ox::core:0.3.6
//> using dep ch.qos.logback:logback-classic:1.5.7
// Remember to set the OPENAI_KEY env variable!
package examples
import ch.qos.logback.classic.LoggerContext
import ch.qos.logback.classic.spi.LogbackServiceProvider
import org.slf4j.spi.{MDCAdapter, SLF4JServiceProvider}
import org.slf4j.{ILoggerFactory, IMarkerFactory, LoggerFactory, MDC}
import ox.{ForkLocal, pipe, tap}
/** Provides support for MDC which is inheritable across (virtual) threads. Only MDC values set using the [[where]] method will be
* inherited; this method also defines the scope, within which the provided MDC values are available.
*
* The semantics of [[MDC.put]] are unchanged: values set using this method will only be visible in the original thread. That is because
//> using dep com.softwaremill.sttp.tapir::tapir-netty-server-sync:1.10.7
import ox.channels.{Actor, ActorRef, Channel, ChannelClosed, Default, DefaultResult, selectOrClosed}
import ox.{fork, releaseAfterScope, supervised}
import sttp.tapir.*
import sttp.tapir.CodecFormat.*
import sttp.tapir.server.netty.sync.{Id, NettySyncServer, OxStreams}
import java.util.UUID
package brc
import monix.eval.Task
import monix.execution
import monix.reactive.Observable
import java.io.{BufferedReader, FileInputStream, InputStreamReader}
import java.text.DecimalFormat
object UsingMonix:
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.concurrent.Exchanger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport;
// with changes inspired by Exchanger
public class Rendezvous2 {
private volatile Thread waiting;
private volatile int data = -1; // together with `consumed`, used to transmit data if t1 wins the race (and waits for t2)
import cats.effect.{Deferred, IO, Ref}
import cats.effect.std.Queue
import cats.effect.unsafe.implicits.global
import java.util.concurrent.Executors
import scala.concurrent.ExecutionContext
// max times rendezvous using cats-effect's synchronous queue
def rendezvousUsingCatsEffect(): Unit =
val max = 10_000_000