Skip to content

Commit

Permalink
Hooked Main into config, this works.
Browse files Browse the repository at this point in the history
development.scala is a config file appropriate for development (TRACE and
such).

serviceClient.rb is a little command line wrapper for interacting with the
service.
  • Loading branch information
bmatheny committed Sep 7, 2011
1 parent 959861d commit 6624f2d
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 13 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@ Some finagle example code for demonstration purposes.
> update
> test
> run -f config/development.scala
$ curl http://localhost:4242/shutdown.txt
$ curl http://localhost:9900/shutdown.txt
> exit

## Ostrich

$ ./sbt
> run -f config/development.scala
$ ./scripts/serviceClient.rb "hello world"
$ curl http://localhost:4242/stats.txt
$ ./scripts/serviceClient.rb "please throw an exception"
$ curl http://localhost:9900/stats.txt

## Configuration

Expand Down
35 changes: 35 additions & 0 deletions config/development.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import net.mobocracy.starter.config._
import com.twitter.conversions.time._
import com.twitter.logging.config._
import com.twitter.ostrich.admin.config._

new StarterServiceConfig {
port = 4242
name = "StarterService"

admin.httpPort = 9900

admin.statsNodes = new StatsConfig {
reporters = new JsonStatsLoggerConfig {
loggerName = "stats"
serviceName = name
} :: new TimeSeriesCollectorConfig
}

loggers =
new LoggerConfig {
level = Level.TRACE
handlers = new ConsoleHandlerConfig {
formatter = new FormatterConfig {
useFullPackageNames = true
prefix = "%s [<yyyyMMdd-HH:mm:ss.SSS>] %s: "
}
}
} :: new LoggerConfig {
node = "stats"
level = Level.FATAL
useParents = false
handlers = new ConsoleHandlerConfig
}

}
37 changes: 37 additions & 0 deletions scripts/serviceClient.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/ruby

require 'socket'
require 'optparse'

options = {
:port => 4242
}
opts = OptionParser.new do |opts|
opts.banner = "Usage: serviceClient.rb [option] text"

opts.on("-p", "--port POT", Integer, "Use the specified port for connecting to the service") do |port|
options[:port] = port.to_i
end
end

def client(data, port = PORT)
begin
sock = TCPsocket.new('127.0.0.1', port)
sock.write(data + "\n")
reply = sock.readline
puts("Sent: #{data}")
puts("Received: #{reply}")
sock.close
rescue Exception => e
puts("Caught exception sending data, is the server listening?")
puts("Exception: #{e.message}")
end
end

opts.parse!
if ( ARGV.length == 0 ) then
puts(opts)
exit
else
client(ARGV[0], options[:port])
end
18 changes: 16 additions & 2 deletions src/main/scala/net/mobocracy/starter/Main.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
package net.mobocracy.starter

import com.twitter.logging.Logger
import com.twitter.ostrich.admin.{RuntimeEnvironment, ServiceTracker}

object Main {
val log = Logger.get(getClass)

def main(args: Array[String]) {
println("Hello World")
System.exit(0)
val runtime = RuntimeEnvironment(this, args)
val server = runtime.loadRuntimeConfig[StarterServiceServer]
try {
log.info("Starting service")
server.start()
} catch {
case e: Exception =>
log.error(e, "Failed starting service, exiting")
ServiceTracker.shutdown()
System.exit(1)
}
}
}
36 changes: 32 additions & 4 deletions src/main/scala/net/mobocracy/starter/StarterService.scala
Original file line number Diff line number Diff line change
@@ -1,22 +1,50 @@
package net.mobocracy.starter

import java.net.InetSocketAddress
import java.security.MessageDigest

import com.twitter.finagle.Service
import com.twitter.finagle.builder.{Server, ServerBuilder}
import com.twitter.finagle.stats.OstrichStatsReceiver
import com.twitter.logging.Logger
import com.twitter.ostrich.stats.Stats
import com.twitter.util.Future

trait StarterService {
val port: Int
val name: String
var server: Option[Server] = None

val service = new Service[String, String] {
def apply(request: String) = Future.value(request)
}
val log = Logger.get(getClass)

val serverSpec = ServerBuilder()
// Don't initialize until after mixed in by another class
lazy val serverSpec = ServerBuilder()
.codec(StringCodec())
.bindTo(new InetSocketAddress(port))
.name(name)
.reportTo(new OstrichStatsReceiver)

val service = new Service[String, String] {
def apply(request: String) = {
log.debug("Got request")
Stats.incr("service_request_count")

val hashedRequest = Stats.time("request_hash") {
getStringHash(request)
}

request match {
case "please throw an exception" =>
Future.exception(new Exception("Asked to throw, don't blame me"))
case _ =>
Future.value(request + "\t" + hashedRequest + "\n")
}
}
}

protected[this] def getStringHash(s: String): String = {
val hasher = MessageDigest.getInstance("SHA-512")
hasher.update(s.getBytes("UTF-8"))
hasher.digest.map { "%02x" format _ }.mkString
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,26 @@ class StarterServiceServer(config: StarterServiceConfig) extends OstrichService
require(config.port > 0, "Need a port to listen on")
require(config.name != null && config.name.length > 0, "Need a service name")

val log = Logger.get(getClass)
val port = config.port
val name = config.name

override def start() {
log.info("Starting StarterServiceServer")
log.debug("Starting StarterServiceServer %s on port %d", name, port)
server = Some(serverSpec.build(service))
}

override def shutdown() {
log.info("Shutting requested")
log.debug("Shutdown requested")
server match {
case None =>
log.info("Server not started, refusing to shutdown")
log.warning("Server not started, refusing to shutdown")
case Some(server) =>
try {
server.close(0.seconds)
log.info("Shutdown complete")
} catch {
case e: Exception =>
log.error(e, "Error shutting down server")
log.error(e, "Error shutting down server %s listening on port %d", name, port)
}
} // server match
}
Expand Down

0 comments on commit 6624f2d

Please sign in to comment.