Skip to content

Commit

Permalink
more comments etc
Browse files Browse the repository at this point in the history
  • Loading branch information
aorwall committed Jan 10, 2013
1 parent 55c438e commit 1b07b43
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import se.callista.loganalyzer.{AccessLog, ConfirmationMessage, LogMessage, Hand
* Tips:
* - Då meddelanden hanteras seriellt i en actor behöver man inte
* oroa sig för att göra variabler trådsäkra, de kan alltså vara "mutable".
* - i++ fungerar inte i skala, använd 'i += 1' eller i = 'i + 1'
* 3. Skicka logg-meddelandet till servern
*
* UPPGIFT 4:
Expand All @@ -26,11 +27,11 @@ import se.callista.loganalyzer.{AccessLog, ConfirmationMessage, LogMessage, Hand
* - En mutable map finns under scala.collection.mutable.Map:
* Lägg till element: map += key -> value
* Ta bort element: map -= key
* - För att köra en metod på alla element i en lista kan foreach användas.
* T.ex "collection.foreach { x -> println(x) }"
* - För att köra en metod på alla element i en map kan foreach användas.
* T.ex "map.foreach { case (k, v) => funktion(v) }"
*
*/
class LogAgent(host: String, server: ActorRef) extends Actor with ActorLogging {
class LogAgent(hostname: String, server: ActorRef) extends Actor with ActorLogging {

def receive = {
case None => //ersätt denna rad med en korrekt pattern matching
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,24 @@ import akka.util.duration._

object LogAgentApplication extends App {

// ladda in konfiguration (agent/src/main/resources/application.conf)
val config = ConfigFactory.load()

// sätt hostname till det hostname som anges i konfigurationen för Akka Remote
val hostname = config.getString("akka.remote.netty.hostname")

// skapa och starta ett nytt actor system för agenten
val system = ActorSystem("LogAgentActorSystem", config)

// peka ut server-actorn som kör på ett annat remote actor system
val server = system.actorFor("akka://[email protected]:2553/user/logServer")

// skapa och starta LogAgent-actorn
val agent = system.actorOf(Props(new LogAgent(hostname, server)), "logAgent")

// skapa och starta reader-actorn som läser loggfilen
// (läsningen simuleras och en slumpad logg skapas en gång i sekunden)
val reader = system.actorOf(Props(new LogReaderSimulator(agent, 25)), "logReader")

val scheduler = system.scheduler.schedule(1 seconds, 1 seconds, reader, Tick)

}
Expand Down
2 changes: 0 additions & 2 deletions common/src/main/scala/se/callista/loganalyzer/Count.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ case class Count(
status: HttpStatus,
count: Int) {

// override def toString = "status: %s, count: %s" format (status, count)

def toJson = "{ \"status\":\"%s\", \"count\": %s }".format(status, count)

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,43 @@ import java.util.Date

object LogServerApplication extends App {

// ladda in konfiguration (server/src/main/resources/application.conf)
val config = ConfigFactory.load()

// peka ut index-fil
lazy val indexFile = io.Source.fromInputStream(getClass.getResourceAsStream("/index.html")).mkString

// skapa och starta ett nytt actor system för servern
val system = ActorSystem("LogServerActorSystem", config)

val activeWebsockets = HashMap[String, WebSocket]()

val send = (msg: String) => activeWebsockets.foreach {
case (_, s: WebSocket) => s.send(msg)
}

val presenter = system.actorOf(Props(new WebSocketPresenter(send)), "webSocket")
// skapa och starta en websocket-actor
val presenter = system.actorOf(Props[WebSocketPresenter], "webSocket")

// skapa och starta LogServer-actorn
val logServer = system.actorOf(Props(new LogServer(presenter)), "logServer")

// peka ut "databasen"
val db = UnstableDatabase

// skapa och starta en webbserver på port 8080
lazy val nettyServer = unfiltered.netty.Http(8080)
.handler(unfiltered.netty.websockets.Planify({
case Path(Seg("socket" :: Nil)) => {
case Open(s) => activeWebsockets += s.channel.getId.toString->s
case Close(s) => activeWebsockets -= s.channel.getId.toString
case Error(s, e) => activeWebsockets -= s.channel.getId.toString
case Open(s) => presenter ! StartSocket(s.channel.getId.toString, s)
case Close(s) => presenter ! StopSocket(s.channel.getId.toString)
case Error(s, e) => presenter ! StopSocket(s.channel.getId.toString)
case Message(s, Text(msg)) =>
}}).onPass(_.sendUpstream(_)))
.handler(unfiltered.netty.cycle.Planify({
case Path(Seg(Nil)) => try {
ResponseString(indexFile)
} catch { case e => BadRequest }
case Path(Seg("logs" :: Nil)) => try {
ResponseString(db.latestTwenty.mkString("\n"))
ResponseString("LATEST 20 LOGS:\n"+db.latestTwenty.mkString("\n"))
} catch { case e => BadRequest }
case _ => ResponseString("Couldn't handle request")
}))

nettyServer.run()

}

Original file line number Diff line number Diff line change
@@ -1,12 +1,34 @@
package se.callista.loganalyzer.server

import scala.collection.mutable.Map
import akka.actor.Actor
import se.callista.loganalyzer.Count
import se.callista.loganalyzer.HttpStatus
import unfiltered.netty.websockets.WebSocket

class WebSocketPresenter (send: String => Unit) extends Actor {
/**
* Skickar ut Count-objekt till aktiva websockets
*/
class WebSocketPresenter extends Actor {

val counts = Map[HttpStatus, Count]()

val sockets = Map[String, WebSocket]()

def receive = {
case c: Count => send(c.toJson)
case c: Count => {
counts += c.status -> c
sockets.foreach{ case (_, s) => s.send(c.toJson)}
}
case StartSocket(id, s) => {
sockets += id -> s
counts.foreach{ case (_, c) => s.send(c.toJson)}
}
case StopSocket(id) => sockets -= id
}

}
}

case class StartSocket (id: String, webSocket: WebSocket)

case class StopSocket (id: String)

0 comments on commit 1b07b43

Please sign in to comment.