Skip to content

Commit

Permalink
First commit of skeleton code
Browse files Browse the repository at this point in the history
  • Loading branch information
henrikengstrom committed Aug 27, 2012
1 parent 2ddeb9f commit 7d4883f
Show file tree
Hide file tree
Showing 9 changed files with 253 additions and 3 deletions.
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
*.class
*.log

# OSX
.DS_Store

# IDEA
.idea
.idea_modules

# ECLIPSE
.classpath
.project
.settings

# sbt specific
dist/*
target/
Expand Down
74 changes: 71 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,72 @@
akka-meetup-sthlm
=================
# Akka Kata for Stockholm Meetup

Akka kata to be used during the Stockholm Scala Meetup group
This repository contains an Akka kata to be used during the Stockholm Scala Meetup group (or whenever you feel like doing some Akka Karate related training).

## Prerequisites

* A computer
* An installed OS
* Java
* [SBT 0.12.0](http://www.scala-sbt.org/download.html)
* [Git](http://git-scm.com/downloads) _(not mandatory)_

## Getting Started (Git installed)

So you decided to install Git (or already had it installed). Smart move!
Open a terminal and type:
__> git clone git@github.com:henrikengstrom/akka-meetup-sthlm.git__

## Getting Started (manually - Git unavailable)

Open a browser and point it to:
__https://github.com/henrikengstrom/akka-meetup-sthlm/downloads__

Select your preferred flavor of compression (zip or tar.gz), download and extract onto your machine.

## SBT

To compile your project code with SBT:
> cd akka-meetup-stockholm
> sbt
> compile
## Eclipse the project

Open a terminal and type:
> sbt eclipse
Open Eclipse and point it to the project catalogue.

## IntelliJ the project

Open a terminal window and type:
> sbt gen-idea
Open IntelliJ and point it to the project catalogue.

## The Kata ("osu sensei")

The aim with this kata is to show some core elements of Akka:
* Remoting
* Supervision
* Some Akka patterns

To showcase the elements above we have selected to implement a simple betting application - or at least provide a skeleton of such an application.
The implemented application should simulate a transacted system, i.e. it should handle a crash of a JVM.
We will discuss pros and cons of alternative implementations during the meetup.

The application you create will run in two different JVMs (and actor systems). One "node", called _ betting service_, receives bet messages from a client,
creates a transaction number and sends this message to the other "node" __betting processor_. The betting service keeps track of messages sent and should also
handle confirmation messages from the betting processor. It also handles re-sending of messages that have not been confirmed.

The task of the betting processor is to spawn workers that do the dangerous job (in this case interacting with an unstable service),
supervise these workers and send back confirmation that a task has been performed.

We will provide some alternative implementations to show how to solve the different tasks/assignments raised in the code (see comments in provided code).

## Authors

* Henrik Engström : [@henke](http://twitter.com/h3nk3)
* Björn Antonsson : [@bantonsson](http://twitter.com/bantonsson)

## Props

Props to [Typesafe](http://www.typesafe.com) for paying for the time taken to implement this kata example.
10 changes: 10 additions & 0 deletions common/src/main/scala/com/typesafe/akkademo/common/Message.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (C) 2011-2012 Typesafe <http://typesafe.com/>
*/
package com.typesafe.akkademo.common

case class Bet(player: String, game: Int, amount: Int)

case class PlayerBet(id: Long, bet: Bet)

case class ConfirmationMessage(id: Long)
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (C) 2011-2012 Typesafe <http://typesafe.com/>
*/
package com.typesafe.akkademo.processor.repository

import com.typesafe.akkademo.common._

trait UnstableResource {
def save(player: String, game: Int, amount: Int): Unit
def findAll: Seq[Bet]
}

class ReallyUnstableResource extends UnstableResource {
import java.util.concurrent.atomic.AtomicInteger

var seq = new AtomicInteger()
val bets = scala.collection.mutable.Map[Int, Bet]()

def save(player: String, game: Int, amount: Int) = {
val id = seq.getAndIncrement
if (id % 3 == 0) throw new RuntimeException("Hey, I did not count on this happening...")
if (id % 5 == 0) throw new DatabaseFailureException("Help. The database's gone haywire!")
bets += id -> Bet(player, game, amount)
}

def findAll: Seq[Bet] = {
bets.values.toSeq
}
}

class DatabaseFailureException(msg: String) extends Exception
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (C) 2011-2012 Typesafe <http://typesafe.com/>
*/
package com.typesafe.akkademo.processor.service

import akka.actor.Actor
import com.typesafe.akkademo.common.PlayerBet

class BettingProcessor extends Actor {

var simulatedActorSystemDeathSequence: Int = 0

/**s
* TASKS :
* Create worker for dangerous task (using UnstableRepository actor)
* Supervise worker -> handle errors
* Send confirmation message back to Betting service
*/

def receive = {
case m =>
// DO NOT CHANGE THE CODE BELOW - USED TO SIMULATE A BIIIG CRASH
simulatedActorSystemDeathSequence += 1
if (simulatedActorSystemDeathSequence % 121 == 0) context.system.shutdown()

// ADD YOUR CODE BELOW
m match {
case bet: PlayerBet =>
}
}
}
71 changes: 71 additions & 0 deletions project/Build.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import sbt._
import sbt.Keys._

object AkkaDemoBuild extends Build {
val Organization = "akkademo"
val Version = "1.0-SNAPSHOT"
val ScalaVersion = "2.9.2"

lazy val akkademo = Project(
id = "akkademo",
base = file("."),
aggregate = Seq(common, processor, service)
)

lazy val common = Project(
id = "common",
base = file("common"),
settings = defaultSettings ++ Seq(libraryDependencies ++= Dependencies.akkademo)
)

lazy val processor = Project(
id = "processor",
base = file("processor"),
dependencies = Seq(common),
settings = defaultSettings ++ Seq(
libraryDependencies ++= Dependencies.akkademo
)
)

lazy val service = Project(
id = "service",
base = file("service"),
dependencies = Seq(common),
settings = defaultSettings ++ Seq(
libraryDependencies ++= Dependencies.akkademo
)
)

lazy val defaultSettings = Defaults.defaultSettings ++ Seq(
resolvers += "Typesafe Repo" at "http://repo.typesafe.com/typesafe/releases/",

// compile options
scalacOptions ++= Seq("-encoding", "UTF-8", "-optimise", "-deprecation", "-unchecked"),
javacOptions ++= Seq("-Xlint:unchecked", "-Xlint:deprecation"),

// disable parallel tests
parallelExecution in Test := false
)
}

object Dependencies {
import Dependency._
val akkademo = Seq(akkaActor, scalaTest, jUnit)
}

object Dependency {
object Version {
val Akka = "2.0.3"
val Scalatest = "1.6.1"
val JUnit = "4.5"
}

// ---- Application dependencies ----

val akkaActor = "com.typesafe.akka" % "akka-actor" % Version.Akka

// ---- Test dependencies ----

val scalaTest = "org.scalatest" % "scalatest_2.9.0" % Version.Scalatest % "test"
val jUnit = "junit" % "junit" % Version.JUnit % "test"
}
1 change: 1 addition & 0 deletions project/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.version=0.12.0
5 changes: 5 additions & 0 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resolvers += Classpaths.typesafeResolver

addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0")

addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.1.0")
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Copyright (C) 2011-2012 Typesafe <http://typesafe.com/>
*/
package com.typesafe.akkademo.service

import akka.actor.Actor
import com.typesafe.akkademo.common.Bet

class BettingService extends Actor {

/**
* TASKS:
* Create unique sequence/transaction number
* Create PlayerBet and call betting processor (remotely)
* Handle timed out transactions (scheduler)
*/

def receive = {
case bet: Bet =>
}
}

0 comments on commit 7d4883f

Please sign in to comment.