

Play, Scala, and Iteratees vs. Node.js and Socket.io - toong
http://brikis98.blogspot.be/2013/11/play-scala-and-iteratees-vs-nodejs.html

======
saryant
Play's documentation on iteratees is definitely dense. One of the contributors
has posted a far better explanation (compared to the docs, not this post) on
his blog:

[http://mandubian.com/2012/08/27/understanding-
play2-iteratee...](http://mandubian.com/2012/08/27/understanding-
play2-iteratees-for-normal-humans/)

I have an weekend project that uses Play's iteratees and enumerators quite
well (IMO). They act as plumbing between client events (interacting with an
embedded map), fetching and writing data to Mongo and interacting with the
FlightAware API. I used server-sent events instead of WebSockets.

I haven't touched the code in a while (and the API key in the repo doesn't
work ;)) but I have a working prototype that tries to stay entirely async:
[https://github.com/ryantanner/flightsight/tree/master/app](https://github.com/ryantanner/flightsight/tree/master/app)

I think the OP is correct in that Play's iteratees/enumerators are fantastic
but too low-level for most applications. Play (or a third-party) need to
provide a high-level abstraction so that developers can ramp up as quickly as
with socket.io.

~~~
curun1r
Perhaps you can clear up my confusion with the article. It appears to me that
Play is basically implementing Rx, except with a pointless new set of
terminology. The Node examples could have all been structured almost
identically to the Play examples if they used rx. What advantages or extra
functionality is enabled by enumerator/enumeratee/iteratee that you can't get
with observable?

~~~
eeperson
A comment in the article, from one of the Play developers, provides a good
explanation about what iteratees provide that is not provided by rx:
[http://brikis98.blogspot.com/2013/11/play-scala-and-
iteratee...](http://brikis98.blogspot.com/2013/11/play-scala-and-iteratees-vs-
nodejs.html?showComment=1385511897410#c3240399653494822522)

~~~
rossjudson
Quoting Roper: _The complexity of iteratees comes because they handle many
different things at once - async io, backpressure, producing results,
composition on multiple different axes. Most other APIs that they get compared
to only handle one or max two of these, so the complexity of those APIs is not
in what they do, but what they don 't do that you have to implement yourself._

------
tilltheis
James Roper wrote a comment describing why Play's iteratees are so complex in
comparison: [http://brikis98.blogspot.de/2013/11/play-scala-and-
iteratees...](http://brikis98.blogspot.de/2013/11/play-scala-and-iteratees-vs-
nodejs.html?showComment=1385511897410#c3240399653494822522)

~~~
saryant
For those who don't know, James Roper is one of the Play contributors.

------
kirinan
As someone who has used both, I have to give this battle to Node.js and
Socket.io. The ease of use because of the common client/server code almost
blurs the line between the client and server and makes it almost a pleasure to
use. Whereas in Play/Scala, there isn't a libary I can use for both the client
and server, thus I either have to write my own client library (or use one) and
then write my server code. From a maintainability standpoint, Node, in this
particular use case, just demolishes Scala/Play.

~~~
leokun
I think it's a bit over the top to compare Scala to JavaScript and node.js.

If you're comparing the two you have way more flexibility than you should
because these are two widely divergent tools with different implications
reaching beyond "easier" or "faster." I don't think people ought to even
consider scala if they're considering "easy" as being a significant factor.

Scala enjoys type safety and compilation and a vast and deep sophisticated
feature set, not the very least of which is inherited from the proven and
storied java libraries. Node.js is a mess of shit heaped on the turd that is
script-kiddy npm-land covered with int-less and unicode unsafe JavaScript.

~~~
jwcooper
This is such an odd argument. As a developer that likes to produce usable
products, 'easy' is something I'm always looking for. Why not? Just because
something is 'easy' doesn't mean it's inadequate. It all depends on what
you're building.

Also, your misguided rant against node and npm rather hurts your credibility.
Your argument was at least ok up until that point.

~~~
leokun
I'm sorry, it is over the top, I'm just so tired of npm libraries I depend on
going dark or changing things without updating the version.

~~~
Q_the_Novice
FIY, npm does not allow you to push a module version more than once.

~~~
leokun
Pretty sure dependencies can come straight from a git url, bypassing npm. Put
something on npm, and in your package.json you can depend on something
straight up from github. npm will install and build that and it may break your
stuff, it's a gamble. Given how dependencies nest into a massive web, you
don't have to use many things before you end up with something that breaks
you.

~~~
elliotf
I think you're looking for npm shrinkwrap:

[https://npmjs.org/doc/cli/npm-shrinkwrap.html](https://npmjs.org/doc/cli/npm-
shrinkwrap.html)

It locks in all dependencies, including dependencies of dependencies, and
turtles all the way down.

~~~
Touche
shrinkwrap just locks down a version of a dependency, if the dependency points
to a git master branch, that's not locked down. shrinkwrap doesn't install any
code. I think his point is valid, although also probably still very rare.

~~~
elliotf
npm will translate the git branch to its commit sha when you `npm shrinkwrap`
so you're pretty well covered.

------
moondowner
Similar to the Node + Socket.io example, here is a Spring 4 + SockJS example
(the example is a trading application instead of chat, but the concepts
underneath are pretty similar):

[http://assets.spring.io/wp/WebSocketBlogPost.html](http://assets.spring.io/wp/WebSocketBlogPost.html)

and the code: [https://github.com/rstoyanchev/spring-sockjs-protocol-
webapp](https://github.com/rstoyanchev/spring-sockjs-protocol-webapp)

------
dkhenry
This has become my common stack along with Angular on the client side. It
makes for some slick interactions when you can have the client acting just
like an actor passing messages back and forth to the server. It might still be
a different language ( JS and Scala ), but since I am using the same flow in
both of them I have been able to adapt.

------
georgewfraser
This is a great demonstration of how bad Play Iteratees are. One of the most
impenetrable and frustrating API's I've ever used. Invariably I'd end up using
the Concurrent._ imperative APIs to work around them.

------
axelf
I'm assuming that the Iteratee companion object uses implicits to get the
client connection. I'd really prefer something more explicit like socket.io's
approach.

~~~
saryant
That assumption is incorrect. Implicits are not used here (for that purpose
anyways).

The client connection is handled by that "WebSocket.using[String]" handler.
This is just a function that takes a function which takes a Request and
returns an Iteratee and an Enumerator. In Play, this is known as an Action.
Actions take Requests and return Results.

You can see that in the type signature of the WebSocket class:
[http://www.playframework.com/documentation/2.2.x/api/scala/i...](http://www.playframework.com/documentation/2.2.x/api/scala/index.html#play.api.mvc.WebSocket)

    
    
      (f: (RequestHeader) ⇒ (Enumerator[A], Iteratee[A, Unit]) ⇒ Unit)
    

So the client connection is not bound using implicits, it's bound when that
function is actually executed. This function (f) is invoked by the router when
a request comes in for that controller action. This is done using
HandlerInvoker:
[http://www.playframework.com/documentation/2.2.x/api/scala/i...](http://www.playframework.com/documentation/2.2.x/api/scala/index.html#play.core.Router$$HandlerInvoker)

Now, my explanation is not the most eloquent nor is it really necessary to
understand all of this, though it certainly helps.

