Monday, October 22, 2012

scala xml wrapper utility


XDoc is a utility wrapper over scala.xml.Elem. It's simplifies xml processing. Following needs to be considered while using this utility:

1) It does not support namespaces. That can easily incorporated - But our use case did not have any namespaces.
2) It does not consider text within an element to be a child element of the container as opposed to normal convention - But text can set and retrieved from an element.


Following REPL session shows how to use it.

Shows how to create an instance XDoc:

scala> var d = XDoc("animals") addChild "tiger" addChild "lion" addAttr("test", "attrValue")
d: XDoc = 
<animals test="attrValue">
  <tiger/>
  <lion/>
</animals>


Querying child count:

scala> d.childCount
res13: Int = 2

Setting text :

scala> d = d.setText("Sample text")
d: XDoc = <animals test="attrValue">
  Sample text
  <tiger/>
  <lion/>
</animals>

Shows that text is not considered as a child:

scala> d.childCount
res14: Int = 2

scala> d = d addChild(XDoc("zebra").addAttr("hasStripes", "true"))
d: XDoc = <animals test="attrValue">
  Sample text
  <tiger/>
  <lion/>
  <zebra hasStripes="true"/>
</animals>

scala> d.childCount
res15: Int = 3

scala> d = d.addAttr("test2", "Value")
d: XDoc = <animals test2="Value" test="attrValue">
  Sample text
  <tiger/>
  <lion/>
  <zebra hasStripes="true"/>
</animals>

Querying attributes. Attributes are an instance of the case class :

case class XAttr(name: String, value: String)

scala> val atrs = d.attrs
atrs: List[XAttr] = List(XAttr(test,attrValue), XAttr(test2,Value))

scala> d.hasAttrs
res16: Boolean = true

scala> d.attr("test2")
res17: Option[XAttr] = Some(XAttr(test2,Value))

scala> d.attr("testxx")
res18: Option[XAttr] = None


Querying childrens :

scala> d.childrenByName("tiger")
res20: List[XDoc] = List(<tiger/>)

scala> d = d addChild((XDoc("tiger").addAttr("male", "true")) addChild "females")
d: XDoc = <animals test2="Value" test="attrValue">
  Sample text
  <tiger/>
  <lion/>
  <zebra hasStripes="true"/>
  <tiger male="true">
    <females/>
  </tiger>
</animals>

scala> d.childrenByName("tiger")
res21: List[XDoc] = 
List(<tiger/>, <tiger male="true">
  <females/>
</tiger>)


Filtering children based on a predicate:

scala> d = d filter(_.name !="zebra")
d: XDoc = <animals test2="Value" test="attrValue">
  <tiger/>
  <lion/>
  <tiger male="true">
    <females/>
  </tiger>
</animals>


Checking existence of children based on predicate:

scala> d exists(_.isChildLess == false)
res22: Boolean = true

scala> val tigerWithFemales = d filter (_.isChildLess == false)
tigerWithFemales: XDoc = 
<animals test2="Value" test="attrValue">
  <tiger male="true">
    <females/>
  </tiger>
</animals>

Mapping over child elements and transforming them:

scala> d = d map (_.addAttr("wild","true"))
d: XDoc = <animals test2="Value" test="attrValue">
  <tiger wild="true"/>
  <lion wild="true"/>
  <tiger wild="true" male="true">
    <females/>
  </tiger>
</animals>


Finding based on a predicate condition on children:

scala> val withFemale = d find(_.isChildLess == false)
withFemale: Option[XDoc] = 
Some(<tiger wild="true" male="true">
  <females/>
</tiger>)

Checking if some conditions holds for all children:

scala> d forall(_.attr("wild") match {
     |   case None => false
     |   case Some(x) => true
     |   })
res23: Boolean = true

Finally, we can partition the elements based on some criteria.

scala> val (d1, d2) = d partition (_.isChildLess)
d1: XDoc = 
<animals test2="Value" test="attrValue">
  <tiger wild="true"/>
  <lion wild="true"/>
</animals>
d2: XDoc = 
<animals test2="Value" test="attrValue">
  <tiger wild="true" male="true">
    <females/>
  </tiger>
</animals>


As can be seen XDoc can be pretty handy for dealing with xmls without namespaces. It is an utility class of a bigger project - And can be improved upon. In the mean while the source can be found at:

https://github.com/ratulb/scala-xml-wrapper









Sunday, June 3, 2012

Cloud Foundry Now Supports Play!

Cloudfoundry now has now incorporated support for play 2.0. Following is the link:

http://blog.cloudfoundry.com/2012/05/31/cloud-foundry-now-supports-play/

Have fun!

Saturday, May 12, 2012

Deploy play 2.0 app on cloudfoundry

For last few days I was trying to find a to deploy my play 2.0 application. I have already deployed my app at heroku(http://ooki.herokuapp.com/). But heroku offers very limited resources for free account (max slug size can not exceed 100MB and only 5MB of shared database space. So you have to work within these constraints and it becomes difficult to play around. In fact, to reduce my slug size I had to use a custom build pack from github. Also, if your application is not accessed for a long - heroku idles out your app - next time you access your app - it takes a long time for the response to come back. So you need to setup some kind ping program to keep hitting your app at regular interval say, every 10 minutes.

With cloundfoundry these problems are not there - cloudfoundry free resources are quite good enough(2GB RAM, 2GB disk space) so that you can concentrate on what you are doing instead of thinking about resource constraint.

Prerequisite:

Before you can deploy your app in cloudfoundry.com - you need to open an account with cloudfoundry.com. After registering it takes a day or two to get your account activated. You also have to have either the vmc command line tool or sts(eclipse plugin) installed on your system - visit the http://docs.cloudfoundry.com/getting-started.html link and follow the instructions there.
r new application is ready.App
Once you have setup the pre-requisites and got your user name and password from cloudfoundry.com - you are all set to deploy your app on cloudfoundry.com Paas.

I am going to use the vmc command line tool to deploy a newly created play 2.0 application on cloudfoundry.

Follow the steps below to deploy your app.

1. Launch command prompt.

2. Type in -> play new myPlayApp

ratul@ubuntu:~$ play new myPlayApp
       _            _
 _ __ | | __ _ _  _| |
| '_ \| |/ _' | || |_|
|  __/|_|\____|\__ (_)
|_|            |__/
            
play! 2.0.1, http://www.playframework.org

The new application will be created in /home/ratul/myPlayApp

What is the application name?
> myPlayApp

Which template do you want to use for this new application?

  1 - Create a simple Scala application
  2 - Create a simple Java application
  3 - Create an empty project

> 1

OK, application myPlayApp is created.

Have fun!

3. Opne the newly created myPlayApp/app/controllers/Application.scala file in a text editor.

Change defintion of the index method like so:

 def index = Action {
    val port = System.getenv("VCAP_APP_PORT")
    val host = System.getenv("VCAP_APP_HOST")
    println("App port : "+ port+" and host: "+ host)
    Ok(views.html.index("Your new application is ready."+ "App port : "+ port+" and host: "+ host))
  }

  Note: VCAP_APP_PORT & VCAP_APP_HOST are port name host names cloudfoundry assigns when it runs your app.

4. Save the Application.scala.

5. Open the myPlayApp/app/views/index.scala.html in a text editor and change the line that reads @play20.welcome(message) to @message and save it.

6. On the command, cd myPlayApp -> ratul@ubuntu:~$ cd myPlayApp/

7. launch the play promt by tying 'play'.

ratul@ubuntu:~/myPlayApp$ play
[info] Loading project definition from /home/ratul/myPlayApp/project
[info] Set current project to myPlayApp (in build file:/home/ratul/myPlayApp/)
       _            _
 _ __ | | __ _ _  _| |
| '_ \| |/ _' | || |_|
|  __/|_|\____|\__ (_)
|_|            |__/
            
play! 2.0.1, http://www.playframework.org

> Type "help play" or "license" for more information.
> Type "exit" or use Ctrl+D to leave this console.

8. Next we will bundle the application. So type 'dist' on the play prompt.

[myPlayApp] $ dist
[info] Updating {file:/home/ratul/myPlayApp/}myPlayApp...
[info] Done updating.                                                                 
[info] Compiling 5 Scala sources and 1 Java source to /home/ratul/myPlayApp/target/scala-2.9.1/classes...
[info] Packaging /home/ratul/myPlayApp/target/scala-2.9.1/myPlayApp_2.9.1-1.0-SNAPSHOT.jar ...
[info] Done packaging.

Your application is ready in /home/ratul/myPlayApp/dist/myPlayApp-1.0-SNAPSHOT.zip

[success] Total time: 12 s, completed 12 May, 2012 2:56:34 PM

9. We want to push the application contents as folder structure and not as zip so that we want to be able to push deltas later on. Hence open the folder myPlayApp/dist in your explorer and extract the contents inside 'myPlayApp-1.0-SNAPSHOT.zip' in the same folder.

10. Delete the myPlayApp-1.0-SNAPSHOT.zip. Go inside the myPlayApp-1.0-SNAPSHOT folder and delete the README and start files as well - we do not need them.

11. Now we are ready to push our content to cloudfoundry. Let's logr new application is ready.Appin first.

12. On the command prompt come out from the play promt by typing 'exit'.

13. cd dist/myPlayApp-1.0-SNAPSHOT/

14. Type 'vmc login' on the command prompt.

ratul@ubuntu:~/myPlayApp/dist/myPlayApp-1.0-SNAPSHOT$ vmc login
Attempting login to [http://api.cloudfoundry.com]

Email: ratul75@hotmail.com
Password: ******************
Successfully logged into [http://api.cloudfoundry.com]

15. On the prompt type : vmc target api.cloudfoundry.com

ratul@ubuntu:~/myPlayApp/dist/myPlayApp-1.0-SNAPSHOT$ vmc target api.cloudfoundry.com
Successfully targeted to [http://api.cloudfoundry.com]

16. When prompted by vmc, answer with y or n as shown below.

ratul@ubuntu:~/myPlayApp/dist/myPlayApp-1.0-SNAPSHOT$ vmc push
Would you like to deploy from the current directory? [Yn]: y
Application Name: myPlayApp
Detected a Standalone Application, is this correct? [Yn]: y
1: java
2: node
3: node06
4: ruby18
5: ruby19
Select Runtime [java]: 1
Selected java
Start Command: java $JAVA_OPTS -Dhttp.port=$VCAP_APP_PORT -cp "`dirname $0`/lib/*" play.core.server.NettyServer `dirname $0`
Application Deployed URL [None]: myPlayApp.${target-base}   
Memory reservation (128M, 256M, 512M, 1G, 2G) [512M]: 256M
How many instances? [1]: 1
Create services to bind to 'myPlayApp'? [yN]: n
Would you like to save this configuration? [yN]: y
Manifest written to manifest.yml.
Creating Application: OK
Uploading Application:
  Checking for available resources: OK
  Processing resources: OK
  Packing application: OK
  Uploading (80K): OK  
Push Status: OK
Staging Application 'myPlayApp': OK                                                 
Starting Application 'myPlayApp': OK     

ratul@ubuntu:~/myPlayApp/dist/myPlayApp-1.0-SNAPSHOT$

17. In your browser you can now open your application - type in myPlayApp.cloudfoundry.com - and we are done!

18. The broswer will show something like :

Your new application is ready.App port : 61897 and host: 172.30.50.24

Monday, January 16, 2012

Delimited continuations

There have been a lot of blog posts, questions & answers about scala's delimited continuation. I would not again try to confuse the reader with another lame-duck explaination. I would, instead, present it as I have come to understand it and then go on to develop a basic framework where we capture a part of a computation and send that frozen computation to a remote machine where it gets executed and result of that computation is sent back to the criginal machine.  
If we think of a scala program as the whole computation - then we can say the whole continuation is from the begining to the end. Let's say whole computation takes value of type A as input and produces a value of type C as output. Also, let's assume the program cosists of 2 functions F1 & F2 which are called in a sequence. So if F is the whole program, then we can write F as follows:

F=F1;F2

So, F1 receives the initial input of type A, computes an intermediate result of type B which is fed to F2 which computes the final result of type C. Now what if we could pause the computation halfway after F1 has calculated it's value and freeze rest of the computation? So the the program now translates into some other function from B => C. Let's call that some other function F~. Now couple of things we need to take notice of here.

Though F~ is a function from B => C, its frozen now - we can pass any value of type B - but it has no effect. We feed some value of type B at the moment we freeze it (via shift). The frozen state extends from end of F1's computation till end F2 computation(this boundary is specified by reset). There might be additional computations after F2 but they are not part of the frozen state. Astute reader by now must have figured out where the delimited qualifier is coming from in scala's continuation. Also, the moment we capture(i.e. freeze) the rest of the computation - control returns to the caller of F but shifting/capturing/freezing must respect the contractual obligation that F returns a value of type C. So, at the point of shifting we must return some value of type C or call F~ with some arbitray value of type B.

Now let's try out a few example before embarking on the business of tossing around delimited continuations. Launch REPL with the continuation pluging enabled as shown below:

scala -P:continuations:enable

scala> class A
defined class A

scala> class B
defined class B

scala> class C
defined class C

scala> import util.continuations._
import util.continuations._

var cont: (B => C) = null

def fun1(a: A): C = {
  println("I am not part of frozen state!")
    reset {
      println("reset marks the boundary where shift/freeze/capture can be done")
      shift { continuation: (B => C) =>
        cont= continuation
        println("I was realized with: "+a.hashCode)
        println("I am returning an arbitrary C")
        new C
      }
      println("I am the part of the frozen computation")
      new C
  }
  println("fun is supposed to return a C")
  new C
}

fun1: (a: A)C

Now let's invoke fun and capture the continuation.

scala> fun1(new A)
I am not part of frozen state!
reset marks the boundary where shift/freeze/capture can be done
I was realized with: 13264767
I am returning an arbitrary C
fun is supposed to return a C
res1: C = C@50d7c5

Now we call cont:

scala> cont(new B)

I am the part of the frozen computation
res2: C = C@3f348a

Let's look at another example:

scala> var cont: (Int => String) = null
cont: (Int) => String = null

scala>

scala> def fun2(i: Int): String = reset {
shift { continuation: (Int => String) =>
cont=continuation
"Ratul Buragohain" //since shift will return control to caller of fun - but fun is supposed to return a String
}
(i to 10).toList.mkString //Changing i's value has no effect after capturing the rest of the computation
}

fun2: (i: Int)String

Call fun to capture the continuation.

scala> fun2(0)

res7: String = Ratul Buragohain

Now call cont.

scala> cont(0)
res8: String = 012345678910

scala> cont(5)
res9: String = 012345678910

scala> cont(null.asInstanceOf[Int])
res12: String = 012345678910

scala> cont(100000000)
res15: String = 012345678910

That's the crux of scala's delimited continuation.

In the next post I will show how we can toss around delimited continuation across machines.