Skip to content

Commit

Permalink
merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyle Maxwell committed May 11, 2011
2 parents 962e2ce + 2002a29 commit 5881a7f
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 40 deletions.
17 changes: 10 additions & 7 deletions README.rdoc
@@ -1,14 +1,17 @@
This creates a standard environment for your twitter-centric sbt/scala thrift service.

Building:

:$ rake build
:$ gem install pkg/scala-bootstrapper-*.gem

Usage:

:$ mkdir foo
:$ cd foo
:$ scala-bootstrapper foo
:$ mkdir birdname
:$ cd birdname
:$ scala-bootstrapper birdname
:$ sbt update test

If you want to track scala-bootstrapper generated files in Git:

:$ scala-bootstrapper --git foo
Tutorial:

To update files (with a new version of scala-bootstrapper), just run it again.
:$ less TUTORIAL.md
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
0.9.1
0.9.2
14 changes: 14 additions & 0 deletions lib/template/README.md
@@ -0,0 +1,14 @@
# Project BirdName

Welcome to your birdname project! To make sure things are working
properly, you may want to:

$ sbt update test

There is a tutorial for what to do next, which you can find in the
scala-bootstrapper README.rdoc file.

# Documenting your project

Add documentation here! Eventually, you'll be able to publish this to
a web site for the world to easily find and read.
162 changes: 162 additions & 0 deletions lib/template/TUTORIAL.md
@@ -0,0 +1,162 @@
# Welcome to BirdName!

## Setup

Scala-bootstrapper has created a fully-functional Scala service for
you. You can verify that things are set up correctly by doing:

$ sbt update test

## Tutorial

### Run your service!

There are two ways to start your service. You can build a runnable
jar and tell java to run it directly:

$ sbt package-dist
$ java -Dstage=development -jar ./dist/birdname/birdname-1.0.0-SNAPSHOT.jar

or you can ask sbt to run your service:

$ sbt 'run -f config/development.scala'

### View the Thrift IDL for your service

The IDL for your service is in src/main/thrift/birdname.thrift. The
Thrift compiler uses the IDL to generate bindings for various
languages, making it easy for scripts in those languages to talk to
your service. More information about Thrift and how to write an IDL
for your service can be found [here](http://wiki.apache.org/thrift/Tutorial)

### Call your service from ruby

Your service implements simple get() and put() methods. Once you have
your server running, as above, bring up a different shell and:

$ bundle install
$ cd birdname
$ ./src/scripts/console
$ $client
$ $client.put("key1", "valueForKey")
$ $client.get("key1")

### Look at the stats for your service

By default, your project is configured to use
[Ostrich](https://github.com/twitter/ostrich), a library for service
configuration, administration, and stats reporting. Your config file
in config/development.scala defines which port ostrich uses for admin
requests. You can view the stats via that port:

$ curl localhost:9900/stats.txt
counters:
Nho2/connects: 1
Nho2/requests: 2
Nho2/success: 2
...

Ostrich also stores historial stats data and can build
[graphs](http://localhost:9900/graph/) for you.

### View the implementation of get() and put()

Take a look at src/main/scala/com/twitter/birdname/BirdNameServiceImpl.scala.

### Try adding some timers and counters

At the top of BirdNameServiceImpl.scala, add:

import com.twitter.ostrich.stats.Stats

Then inside get():

Stats.incr("birdname.gets")

and inside put():

Stats.incr("birdname.puts")

Then restart your server, talk to the server via console, and check
your stats:

$ curl localhost:9900/stats.txt
counters:
BirdName/connects: 1
BirdName/requests: 2
BirdName/success: 2
birdname.gets: 1
birdname.puts: 1

You can also time various things that your server is doing, for
example:

Stats.time("birdname.put.latency") {
Thread.sleep(10) // so you can see it
database(key) = value
}

### Specs: let's add some tests

[Specs](http://code.google.com/p/specs/) is a Behavior-Driven Design
framework that allows you to write semi-human-readable descriptions of
how your service should behave and test that those descriptions are
valid. You already have some Specs code for your project in
src/test/scala/com/twitter/birdname/BirdNameServiceImpl.scala. Check
out the existing test and add a new one for the counter functionality
we just added.

import com.twitter.ostrich.stats.Stats

...

"verify stats" in {
val counters = Stats.getCounters
foofa.put("name", "bluebird")()
foofa.get("name")() mustEqual "bluebird"
counters.getOrElse("foofa.gets", 1) must_==1
counters.getOrElse("foofa.puts", 1) must_==1
}

TODO: add link to scala school lesson on Specs

### Automatically compile and test your server when you change code

By now you've had to Ctrl-C your server and restart it to get changes
to show up. This gets a little tiresome. The build tool we are
using,
[SBT (simple build tool)](http://code.google.com/p/simple-build-tool/)
has a console that you can access by just running "sbt" from the
command line.

$ sbt
[info] Standard project rules 0.11.4 loaded (2011-03-18).
[warn] No .svnrepo file; no svn repo will be configured.
[info] Building project birdname 1.0.0-SNAPSHOT against Scala 2.8.1
[info] using BirdNameProject with sbt 0.7.4 and Scala 2.7.7

SBT has a wide array of features, but a useful one right now is to
use the "~ test" command.

> ~ test

The tilde tells SBT to look for changes to your source files and
re-execute the command when it detects a change.

TODO: add link to scala school lesson on SBT

### Add an admin / dashboard page.

### Add a new dependency to your project, perhaps twitter/util?

### Take a tour of the logs our service is producing.

### Add command-line parameters for your service.
-D foo=bar
runtime.arguments.get("foo")

### Storage: let's persist the data in Cassandra!

### Twitter API: let's listen to the Firehose!

### Twitter API: let's fetch some statuses & users & stuff.
62 changes: 30 additions & 32 deletions scala-bootstrapper.gemspec
@@ -1,6 +1,6 @@
# Generated by jeweler
# DO NOT EDIT THIS FILE DIRECTLY
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
# -*- encoding: utf-8 -*-

Gem::Specification.new do |s|
Expand All @@ -9,48 +9,46 @@ Gem::Specification.new do |s|

s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Kyle Maxwell"]
s.date = %q{2011-04-11}
s.date = %q{2011-04-15}
s.default_executable = %q{scala-bootstrapper}
s.description = %q{Twitter scala project init}
s.email = %q{kmaxwell@twitter.com}
s.executables = ["scala-bootstrapper"]
s.extra_rdoc_files = [
"LICENSE",
"README.rdoc"
"README.rdoc"
]
s.files = [
".document",
".gitignore",
"HACKING",
"LICENSE",
"README.rdoc",
"Rakefile",
"VERSION",
"bin/scala-bootstrapper",
"lib/template/.gitignore",
"lib/template/Capfile",
"lib/template/Gemfile",
"lib/template/config/development.scala.erb",
"lib/template/config/production.scala.erb",
"lib/template/config/staging.scala.erb",
"lib/template/config/test.scala.erb",
"lib/template/project/build.properties",
"lib/template/project/build/BirdNameProject.scala.erb",
"lib/template/project/plugins/Plugins.scala.erb",
"lib/template/run",
"lib/template/src/main/scala/com/twitter/birdname/BirdNameServiceImpl.scala.erb",
"lib/template/src/main/scala/com/twitter/birdname/Main.scala.erb",
"lib/template/src/main/scala/com/twitter/birdname/config/BirdNameServiceConfig.scala.erb",
"lib/template/src/main/thrift/birdname.thrift.erb",
"lib/template/src/scripts/console.erb",
"lib/template/src/scripts/startup.sh",
"lib/template/src/test/scala/com/twitter/birdname/AbstractSpec.scala.erb",
"lib/template/src/test/scala/com/twitter/birdname/BirdNameServiceSpec.scala.erb",
"scala-bootstrapper.gemspec",
"vendor/trollop.rb"
"HACKING",
"LICENSE",
"README.rdoc",
"Rakefile",
"VERSION",
"bin/scala-bootstrapper",
"lib/template/.gitignore",
"lib/template/Capfile",
"lib/template/Gemfile",
"lib/template/config/development.scala.erb",
"lib/template/config/production.scala.erb",
"lib/template/config/staging.scala.erb",
"lib/template/config/test.scala.erb",
"lib/template/project/build.properties",
"lib/template/project/build/BirdNameProject.scala.erb",
"lib/template/project/plugins/Plugins.scala.erb",
"lib/template/run",
"lib/template/src/main/scala/com/twitter/birdname/BirdNameServiceImpl.scala.erb",
"lib/template/src/main/scala/com/twitter/birdname/Main.scala.erb",
"lib/template/src/main/scala/com/twitter/birdname/config/BirdNameServiceConfig.scala.erb",
"lib/template/src/main/thrift/birdname.thrift.erb",
"lib/template/src/scripts/console.erb",
"lib/template/src/scripts/startup.sh",
"lib/template/src/test/scala/com/twitter/birdname/AbstractSpec.scala.erb",
"lib/template/src/test/scala/com/twitter/birdname/BirdNameServiceSpec.scala.erb",
"scala-bootstrapper.gemspec",
"vendor/trollop.rb"
]
s.homepage = %q{http://github.com/fizx/scala-bootstrapper}
s.rdoc_options = ["--charset=UTF-8"]
s.require_paths = ["lib"]
s.rubygems_version = %q{1.3.6}
s.summary = %q{Twitter scala project init}
Expand Down

0 comments on commit 5881a7f

Please sign in to comment.