Play! Framework – część I

Z związku z moim zainteresowaniem Scalą i Akką naturalnym jest zajęcie się ostatnim elementem stosu reaktywnych technologii dla JVM od Typesafe – frameworkiem Play. Niniejszy wpis stanowi, mam nadzieję, pierwszy z serii wpisów opisujących moją przygodę z tym frameworkiem.

Czym jest Play?

Play jest moim zdaniem najlepszym frameworkiem ogólnego przeznaczenia dla JVM
Ogólnie rzeczy ujmując Play to implementacja wzorca MVC w oparciu o model aktów Akka połączona ze środowiskiem do zarządzania projektem i uruchamiania go

Co w nim tak bardzo mi się podoba?

Jednym z głównych filarów architektonicznych Play jest podejście bezstanowe i asynchroniczne.  W Play nie ma tradycyjnej „sesji”. Takie podejście nastręcza czasami pewne trudności, ale są one z nawiązką rekompensowane przez zalety takie jak łatwość horyzontalnego skalowania i wsparcie dla technologi reaktywnych. I Scala. Uwielbiam Scalę.

Zacznijmy jednak od podstaw.

Szkielet aplikacji Play można łatwo wygenerować za pomocą narzędzia Typesafe Activator  – activator new [name] [template-id] – ale nie jest dobry sposób na rozpoczęcie przygody z Play.

activator new my-play-app play-scala

Zacznijmy więc od minimalnej aplikacji Play do której będziemy dodawać kolejne elementy w miarę potrzeby. Minimalna aplikacja jest naprawdę niewielka i składa się z czterech plików z których jeden (application.conf) jest pusty a jeden (build.properties) tak naprawdę  opcjonalny.

$ ls -R
.:
build.properties build.sbt conf/ project/

./conf:
application.conf

./project:
plugins.sbt

build.sbt

name := """my-play-app"""

version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.11.7"

resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"

project/plugins.sbt

// The Play plugin
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.4")

project/build.properties

sbt.version=0.13.11

Nie jest to co prawda zbyt przydatna aplikacja – ale kompiluje się i uruchamia bez przeszkód o czym możemy się przekonać wydając polecenie activator ~run w katalogu aplikacji.

Skrypt wykonujący poszczególne krotki jest dostępny jako Gist

bash <(curl -fsSL https://git.io/vKW88) my-play-app

Running Linux graphical applications in Docker on Windows with Cygwin/X

Install Babun

Cygwin is a great tool, but not the easiest to install. Babun consists of a pre-configured Cygwin  that does not interfere with existing Cygwin installation.

Download the dist file from http://babun.github.io, unzip it and run the install.bat script. After a few minutes the application will be installed to the %USERPROFILE%\.babun directory. You can use the /target (or /t)  option to install babun to a custom directory.

Install Cygwin/X

Run pact from babun shell (pact is a babun package manager )

pact install xorg-server xinit xhost

Start the X server

Once the installation has completed, open a Cygwin terminal and run XWin :0 -listen tcp -multiwindow. This will start an X server on Windows machine
with the ability to listen to connections from the network (-listen tcp) and display
each application in its own window (-multiwindow), rather than a single window acting
as a virtual screen to display applications on. Once it’s started, you should see an
„X” icon in Windows tray area.

Run graphical application

fr3nd/xeyes  is a good test to run

// don't forget to change WINDOWS_MACHINE_IP_ADDR!
// 'localhost' obviously won't work from within Docker container
docker run -e DISPLAY=$WINDOWS_MACHINE_IP_ADDR:0 --rm fr3nd/xeyes

Or we can build ourselves image with Firefox using the following Dockerfile as a starting point

FROM centos

RUN yum -y update && yum install -y firefox

CMD /usr/bin/firefox

docker build -t firefox . it and run the container with

export DISPLAY=$WINDOWS_MACHINE_IP_ADD:0
docker run -ti --rm -e DISPLAY=$DISPLAY firefox

If all goes well you should see Firefox running from within a Docker container.

Troubleshooting

If you have issues with authorization you may want to try running the insecure xhost + command to permit access from all machines. See xhost(1) Linux man page.

Alternatives

There are a few different options to run GUI applications inside a Docker container like using SSH with X11 forwarding or VNC.

Podstawy Akka – izolacja aktorów

Aktorzy w Akka mogą się komunikować tylko przez asynchroniczne przesyłanie komunikatów. Do wysłania komunikatu potrzebny jest uchwyt na aktora (lub selecja) który może być uzyskany w wyniku

  • rodzicielstwa (parenthood) – aktor A tworzy B więc posiada na niego referencję
  • obdarowania (endowment) – kiedy A tworzy B może mu przekazać cześć lub wszystkie uchwyty które sam posiada
  • przedstawienia (introduction) –  jeśli aktor A posiada uchwyty na B i C może wysłać do C komunikat zawierający uchwyt do B. B może wówczas zachować ten uchwyt do dalszego użycia
  • selekcji – w praktyce selekcja jest bardzo podobna do uchwytu. Aktor może wyszukać innych aktorów po nazwach stosując m.in wyrażenia wieloznaczne (context.actorSelection(„/user/*”)) i ścieżki względne (context.actorSelection(„../*”))

 

http://doc.akka.io/docs/akka/current/general/addressing.html

Scala partial function literal

In Scala there’s no literal for partial function types. You have to give the exact signature of the PartialFunction

Though I personally prefer to use type ascription bacause you can define and lift in the same place if needed.

It’s unwieldy, but I’ve learned to live with it.

But lately someone (can’t remember who – sorry!) told me that you don’t need a literal because you can write your own type alias and use it with infix operator concise syntax.

Changing the directory for Vagrant boxes

The successfully downloaded Vagrant boxes are located at ~/.vagrant.d/boxes on Mac/Linux System and %USERPROFILE%/.vagrant.d/boxes on Windows. This can be changed by setting an environment variable named VAGRANT_HOME to specify the location of .vagrant.d, as in VAGRANT_HOME=F:\.vagrant.d

# Windows
# current terminal session
set VAGRANT_HOME=F:\.vagrant.d
# current user environment
setx VAGRANT_HOME F:\.vagrant.d
# system wide environment
setx VAGRANT_HOME F:\.vagrant.d /M

VAGRANT_HOME is documented here along with other interesting options.