Return to the Monolith

lance@lbpaine.com   

 github @somanythings     

twitter @lbpaine

What/why/how?

Tirau

Bio

Text

London

10 years

  • hedge funds
  • HFT
  • banks
  • media

Home Office

DRT

Dynamic Response Tool

Major 'Ports

Queues

SLA

Guessperience

FlightStats

MAN, LHR,

BHX, GLG etc

PHP

MySQL

 

 

 

 

Front End

API

Crunch live

Crunch forecast

Scala

(ish)

DeskStats

PAL

RabbitMq

loader

Configuration

So what to do?

speed of feature change

all ports are NOT the same

shrunken team

Fix It?

Spike!

Backend

  • Renjin
  • akka-streams
  • akka-persistence

Renjin

  • easy to setup
  • 500x-1000x faster

akka-streams

  • Not clear who the documentation is targeting
  • Missing some cookbook approaches
  • We did spike a pure stream which was pretty

akka-persistence

  • gives you PIT views
  • exploding mailbox
  • thou must snapshot
  • choose serialisation wisely
  • moving target, but,
  • docs are great

scalajs with react

this was very early

object versions {
    val scala = "2.11.8"
    val scalaDom = "0.9.1"
    val scalajsReact = "0.11.1"
    val scalajsReactComponents = "0.5.0"
    val scalaCSS = "0.4.1"
    
    val autowire = "0.2.6"
    val booPickle = "1.2.4"
    val diode = "1.0.0"
    val uTest = "0.4.3"

    val react = "15.1.0"
    val jQuery = "1.11.1"
    val bootstrap = "3.3.6"
    val chartjs = "2.1.3"

    val playScripts = "0.5.0"
    val sprayVersion: String = "1.3.3"
    val json4sVersion = "3.4.0"
  }

Teething

pre webpack, sbt

 

early scalajs-react

 

scalajs

  • mostly just worked

scalajs

  • uTest was great,
    • but failures a bit weird

scalajs

  • autowire 
  • beware immutable.Seq

scalajs

  • lihaoyi 
  • diode
"io.suzaku" %% "diode" % "1.1.3"

 

 

 

case class Increase(amount: Int) extends Action
case class Decrease(amount: Int) extends Action
case object Reset extends Action

object AppCircuit extends Circuit[RootModel] {
  def initialModel = RootModel(0)
  override val actionHandler: HandlerFunction =
    (model, action) => action match {
      case Increase(a) => Some(ModelUpdate(model.copy(counter = model.counter + a)))
      case Decrease(a) => Some(ModelUpdate(model.copy(counter = model.counter - a)))
      case Reset => Some(ModelUpdate(model.copy(counter = 0)))
      case _ => None
    }
}

Diode - Circuit

// use an action handler to get composeable handlers

val counterHandler = new ActionHandler(zoomTo(_.counter)) {
  override def handle = {
    case Increase(a) => updated(value + a)
    case Decrease(a) => updated(value - a)
    case Reset => updated(0)
  }
}
val actionHandler = composeHandlers(counterHandler)

Diode - Circuit


//the view
class CounterView(counter: ModelR[Int], dispatch: Dispatcher) {
  def render = {
    div(
      h3("Counter"),
      p("Value = ", b(counter.value)),
      button(onclick := { () => dispatch(Increase(2)) }, "Increase"),
      button(onclick := { () => dispatch(Decrease(1)) }, "Decrease"),
      button(onclick := { () => dispatch(Reset) }, "Reset")
    )
  }
}

Diode View

val root = document.getElementById("root")
AppCircuit.subscribe(() => render(root))
AppCircuit(Reset)

def render(root: Element) = {
  val e = div(
    h1("Diode example"),
    counter.render
  ).render
  root.innerHTML = ""
  root.appendChild(e)
}

Top Render

Original Fan In and Out

Separate instance per 'port

What we used

  • architectural decision records 
  • scalajs
  • scalajs-react  https://github.com/japgolly/scalajs-react
  • diode https://github.com/suzaku-io/diode
  • autowire https://github.com/lihaoyi/autowire
  • our project
    • https://github.com/somanythings/drt-scalajs-spa-exploration
    • or what it is now https://github.com/UKHomeOffice/drt-scalajs-spa-exploration

Questions?

lance@lbpaine.com   

 github @somanythings     

twitter @lbpaine

Made with Slides.com