13 Aug 2010

London, 7-8 Oct 2010: Scala Lift Off

Sessions

I have my ticket. How about you?  It's £150 at the moment.

What we're looking at here is a two day unconference, meaning we get a chance to learn about things we're interested in by figuring it out on the day, talking to people, rather than being lectured at.  I thoroughly enjoyed the Scala Lift Off last year in San Francisco, so I'm looking forward to the London one.  Especially as it close by, rather than 8,720km away.

13 Aug 2010

If you like web MVC, you'll probably like the Play web framework.

 

Play is a MVC, convention-based, stateless web framework for Java with growing support for Scala too.

It's not for me as I can't face going back to MVC and the kinds of presentation languages they use. Having said that, if you like MVC, and you're not already using Grails or Rails or a similar framework, I strongly urge you to look at Play as there's some nice technology in there. 

Everything I know about Play comes from Rustem Suniev's talk for the London Scala User Group at Skilsmatter on Wednesday. The slides and video are already on-line and they contain a really nice live-coding demo of Play which gave me a good sense of what the framework is about.  Nice work—and pizza courtesy of autoquake.com (who are hiring).

One comment I will make is that Play pushes it's stateless-ness prominently. For many of us I suspect our default position is that stateful=bad and stateless=good.  That sounds sane, but you probably do need some state in your application, and you have to deal with it somehow, or push the issue somewhere, which leaves me feeling that state v. stateless thing is all a bit more complicated that we often think it is.  It certainly does not automatically mean better scaling or performance, but there are definite positives to it.  I'm glad to see the Play community discussing state and exploring some nice ideas.  Just don't assume a label of "stateless" solves all your scaling problems—if you're lucky enough to have any :-)

 

26 Jul 2010

Publishing builds from Hudson to S3 & on to EC2 instances.

The plan: have Hudson publish successful builds into a bucket on S3, and then be able to pull those builds to EC2 instances. The result: success, but it took a bit of head scratching.

Step 1: I wasn't able to get Doug MacEachern's S3 Hudson plugin to work with Hudson 1.367, but on reflection I may have just not been using it properly (this is ok: I can look an idiot so you don't have to).  So that'll probably work for you, but I ended up forking the source, updating the code to match the latest Hudson API and adding some error reporting (although similar error reporting can be found in Steve Gilardi's fork). 

I know pretty close to nothing about developing Hudson plugins, so I followed what appears to be a tradition of looking at the source of the scp Hudson plugin and figuring things out from there.

Building the plugin is straight-forward:
 
 $ git clone git://github.com/d6y/hudson-s3.git
 $ cd hudson-s3
 $ mvn package

...you'll get errors about Base64 Codec, but you'll end up with target/s3.hpi which you can install in Hudson and then...

Step 2: configure

The screen shots show you what to do, but in summary: define a profile (your AWS credentials) globally; then for each project, set it to publish particular files to particular buckets using the profile.

Run your build, and files appear on S3.

Step 3: the final step is to be able to pull those build artefacts to your EC2 instances. There are lots of ways to do this, but the option I wanted to try was just using cURL. And you can do that, because S3 supports query string authentication. The idea is you define what you want to access (GET /bucket/file), how long the access should be available for (in seconds since the disco era), and then you sign those details. Stuff all of that into a request, and you can download the file. The details are fiddly, so I've put the script on Assembla for anyone to hack around with. The output is a URL that looks like this:

curl -o foo.war 'https://s3-eu-west-1.amazonaws.com/bucket/foo.war?AWSAccessKeyId=ABCD123456789&Expires=1601719200&Signature=Pkd742kjJKHfku8%3D'

In summary, this all seems to work. 
 
Additional clues:
  • By adding the extra error reporting to the plugin I discovered that Hudson needed more -Xmx to push the build artefacts to S3 (384m rather than the 256m default we'd given it).  
  • If things don't appear to be working, it may be helpful to create a custom Java logging file and start Hudson with it:  java -Djava.util.logging.config.file=log.properties -jar hudson.war 
 

 

 

15 Jul 2010

Scaling web apps with Akka

     
Click here to download:
scaling-web-apps-with-akka-vHotFvgaDFtkrCIuHpbB.zip (284 KB)

Last night I attended Maciej Matyjas "Scaling Web Apps with Akka" LSUG talk at Skillsmatter. The video and slides are online, and @kingsleydavies was live blogging the event, so I won't repeat the details here.

There were a couple of things I particularly liked: getting coverage of the various styles of actors available in Scala; and seeing a different development style. I won't be switching back to emacs any time soon, but I do now see the appeal of SBT.

Do go check out the talk: it goes from zero through actors and a
complete Lift web app talking to Akka actors.

13 Jul 2010

Please stop commenting your code

Code is the easy part to understand. Instead, spend your time giving me the broad clues as to how the code base hangs together: the concepts, the intentions, the analogies, your thinking, how you see it being used.  And then tell me the gotchas.  

How about only writing code comments when there's something newsworthy to say?  Or giving me an example, or pointing me at a test if tests are rare?  What if we accept that our project and team has conventions, and we kind of get them, so you don't need to cover them off in comments? There would be fewer comments, and those that survive would be more likely to be useful.  

The alternative is a nice formatted file with standard or bland comments that will just fade out as background noise---noise which is often (a) pointless and (b) out of date.  And possibly the worst of all this, comments that are just taking up space on my screen, and masking actual useful information that might possibly be buried under some "returns a list of users from the database"-style worthless comment. 

I'm not saying no to comment.  What do you think of this: 
For instance, would you rather use a one-liner that requires a 3-line comment, or a 10-liner that requires no comments? In most cases, code's readability suffers more when it's overly verbose than when it has a high comment to code ratio. Thus, I would choose to write the comment in most cases.

Only a year ago I had the opposite opinion, but now I'm in total agreement. Plus, if you find a funky or idiomatic one-liner the comment would pass that technique on to the team. But please only do that once: don't copy and paste the comment with the code.

Yes, I've joined the anti-comment bandwaggon.  

Yes, I know it's a bit more complicated than that.  

21 Jun 2010

Creating a executable script from a Maven project

If you have a Maven project with a bunch of dependencies, and you've written a harness to launch your thing, it's handy to be able to create a shell script to run your harness with all your dependencies on the classpath.  The Maven assembler plugin is what you need.

In your pom:

<build>
 <plugins>
   ... 
   <plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>appassembler-maven-plugin</artifactId>
   <configuration>
      <programs>
        <program>
           <mainClass>com.example.yourApp.YourClassWithMainMethod</mainClass>
           <name>my_cool_app</name>
        </program>
      </programs>
    </configuration>
   </plugin>
  </plugins>
</build>

Then run:

$ mvn package appassembler:assemble

This produces a shell (and .bat) script in target/appassembler:

$ sh target/bin/my_cool_app
Hello world!

This is one of those "I keep forgetting how to do this so I'd better blog it so I can find it later" kind of posts: It's not original, but handy, and I keep forgetting to run the package part of the Maven command.

14 Jun 2010

Receive & respond to SMS

One part of Taykt.com which I've not spoken much about is the web hooks facility built in.  It means you can write applications which are prodded when a text message arrives, giving you a chance to decide how you want to reply.  I can't think of an easier way get up and running with a SMS-based application: if you can write a web app, you can handle SMS, and you can do it without having to get out a credit card.

To fix the problem of keeping this so quiet, we've documented what we have at Assembla and started to pull together examples. There's a simple echo example (responding to a text message with what was texted in), but I have in my mind plans for other examples.  My favourite would be to see The Internet Oracle implemented, although I also have a soft spot for Eliza and information services... the Taykt.com blog is collecting together ideas for how Taykt.com can be used.

We've also set up a RESTful API for managing accounts, trying to follow as much of the best practices as possible. But I think the web hooks part of the product is the most useful part to just be able to create something and have it running live.

 

 

3 May 2010

Databinder Dispatch for HTTP services

I do like Databinder Dispatch. It wrappers HttpClient and adds in support for oAuth, Twitter and other web services, letting you write code like this:

import dispatch._
import Http._
val http = new Http
http("http://databinder.net/dispatch/Stdout_Walkthrough" >>> System.out)

I admit it might seem a little odd the first time you dig in to use it.  What I found useful was looking at the source which has been formatted with Scala X-Rays—itself quite a eye opener, giving something as useful as an IDE in a browser without actually having an IDE in a browser.

What's happening with the http(...) call is a HttpClient is being invoked via a Handler.  That is, the parameter to the http() call needs to be a Handler, and a Handler is something that takes a request and... handles it, by making use of what comes back from the request, for example.

How do you get a Handler?  You can write your own, but another way is to take a Request and call a method on the Request to give you a Handler.  In the above example the String "http://databinder..." is converted to a Request via an implicit in scope as a result of the import.  The >>> method on the Request gives you a Handler.  In this case, it's a Handler that writes the response to the given stream.

As you might imagine there are lots of methods to give you all sorts of different Handlers, and these can be chained in various ways to set headers, perform POSTs, set encodings.... there's quite a list in Http.scala.

You need to do asynchronous HTTP? It's there. Dealing in Json?  Yup, that's there too.  An impressive library.

Aside:

If you want to just grab some content, work with the content, and return something you could write:

def withContentFrom[T](url: String)(f: String => T): T = new Http().apply(new Request(url) >- f) 

val result = withContentFrom("http://whatever.example.com") { html =>
  // do you thing with html
}

Handy for scripting.

 

 

 

27 Apr 2010

In Praise of flatMap

In Scala the flatMap operation is astonishingly useful in everyday programming. The texts on Scala that I've read only hint at how useful it is: Beginning Scala probably does the best job, and even then you could miss it.  So I'll give it a go...

Map is an operation you probably know pretty well.  It takes a function of type A⇒ B, and applies it to everything in your collection of As so you end up with a collection of Bs:

Welcome to Scala version 2.7.7.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_17).
Type in expressions to have them evaluated.
Type :help for more information.


scala> List(1,2,3) map { num => "I like to count: "+num }
res0: List[java.lang.String] = List(I like to count: 1, I like to count: 2, I like to count: 3)

In this case we're mapping Int => String, and given a list of Ints we get back a list of Strings. Simple.

The signature for flatMap is different.  It expects a function of type A ⇒ Iterable[B]. In the above example, if we started with our list of Ints, we'd need to supply a function for flatMap that, when called on each Int, returned a List[String].  Which just goes to show that I picked a poor example, as it's hard to see how that'd be useful.  But where flatMap comes into its own is with real code when you use Option.  

The thing about Option is that you can think of it like a List that happens to contain either zero items or one item.  When you think of it like that it makes sense for Option to behave as a thing that can be iterated over. Sure, you'll only get at most one iteration, but the principle applies, and indeed Option does implement filter, foreach, and map.  This means, via mechanisms I'm a little hazy on, you can happily call flatMap with a function that maps Option[B] because of this property of Option behaving like an Iterable.

Combine this with the fact that flatMap will drop entries that are empty (which for Option means None) and you have a way to get at all the useful content of a List.  Here's a cut down example of processing some XML, where we're going to extract a list of numbers, but only if we can make sense of the numbers.

scala> import scala.xml._
import scala.xml._


scala> val xml = <outer><ul><li>1</li><li>2</li><li/><li></li><li>4</li></ul></outer>
xml: scala.xml.Elem = <outer><ul><li>1</li><li>2</li><li></li><li></li><li>4</li></ul></outer>


scala> def f(li: NodeSeq) : Option[Int] = {
    | val content = li.text
    | if (content != "")
    |    Some(content.toInt)
    | else
    |    None
    | }
f: (scala.xml.NodeSeq)Option[Int]


scala> xml \ "ul" \ "li" flatMap f 
res1: Seq[Int] = ArrayBufferRO(1, 2, 4)

We took some XML, and for all the <ul> tags, for all the <li> tags, we applied the f function via flatMap.  This function, f, returns either Some[Int] (useful) or None (not useful), and flatMap glues all the useful values together for us.  

To me that's a powerful tool for getting stuff done without a lot of code.

Aside:

flatMap also works well with pattern matching, especially when you're not expected to catch all cases.  The above could have been written as...

xml \ "ul" \ "li" flatMap { case <li>{num @ _*}</li> => num } map { _.text.toInt }

...separating the "finding of useful stuff" step from the "turning it into an Int" step.  

 
25 Mar 2010

Shell aliases for Lift development

Last night I was asked about the aliases I used during my Lift talk.  Here they are...

$ cat ~/.profile
export REBEL_JAR=/Users/richard/Developer/libs/javarebel/jrebel-2.1a/jrebel.jar 
export MAVEN_HOME=/Users/richard/Applications/maven/apache-maven-2.2.1
export MAVEN_OPTS="-Xmx256M -XX:MaxPermSize=256m -Dfile.encoding=utf8"
export JAVA_OPTS="-Dfile.encoding=utf8"
export PATH=$MAVEN_HOME/bin:$PATH

# E.g., "m package" to run the Maven package target in offline mode:
alias m='mvn -o'


# Run Maven in a mode that fetches sources and documentation for libraries:
alias mm='mvn -DdownloadJavadocs=true -DdownloadSources=true'


# Start your Lift application in the REPL
alias liftconsole='mvn -o scala:console -DmainConsole=LiftConsole'


# Start your Lift application using JRebel
alias mmm='MAVEN_OPTS="-Dfile.encoding=utf8 -XX:MaxPermSize=256m -Djetty.scanIntervalSeconds=0 -noverify -javaagent:$REBEL_JAR" mvn -o jetty:run'


# Create a new 2.0-M2 Lift application
alias liftcreate="mvn archetype:generate -DarchetypeGroupId=net.liftweb -DarchetypeArtifactId=lift-archetype-basic -DarchetypeVersion=2.0-M2 -DremoteRepositories=http://scala-tools.org/repo-releases" 

 

Richard Dallaway's Posterous

Director at Spiral Arm Ltd. We build stuff using Scala+Lift, offer consulting & create new projects. I live in Brighton, UK.