-
Notifications
You must be signed in to change notification settings - Fork 1
/
Application.scala
executable file
·109 lines (88 loc) · 3.2 KB
/
Application.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package controllers
import java.io.{ByteArrayOutputStream, File}
import akka.actor.Props
import akka.util.Timeout
import com.typesafe.jse.Engine.JsExecutionResult
import com.typesafe.jse.{Engine, Node, JavaxEngine, Trireme}
import io.apigee.trireme.core._
import play.api.Play.current
import play.api._
import play.api.libs.concurrent.Akka
import play.api.libs.concurrent.Execution.Implicits._
import play.api.libs.json.Json
import play.api.mvc._
import play.twirl.api.Html
import ui.HtmlStream
import scala.concurrent.Promise
import scala.concurrent.duration._
object Application extends Controller {
def index = Action {
Ok(views.html.explanation())
}
def clientSide = Action {
Ok(views.html.index())
}
private def initialData() = Comments.CommentRepository.getComments map { comments =>
Json.stringify(Json.toJson(comments))
}
// with trireme directly
def serverSide = Action.async {
initialData flatMap { data =>
val serverside = Play.getFile("public/javascripts/serverside.js")
val stdout = new ByteArrayOutputStream()
val env = new NodeEnvironment()
val sandbox = new Sandbox()
sandbox.setStdout(stdout)
val script = env.createScript("serverside.js", new File(serverside.toURI), Array(data))
script.setSandbox(sandbox)
val htmlResult = Promise[Result]()
script.execute().setListener(new ScriptStatusListener() {
override def onComplete(script: NodeScript, status: ScriptStatus): Unit = {
val result = stdout.toString("UTF-8")
htmlResult.success(Ok(views.html.index(Html(result))))
}
})
htmlResult.future
}
}
def serverSideJavax = serverSideWithJsEngine(JavaxEngine.props())
// with js-engine
def serverSideTrireme = serverSideWithJsEngine(Trireme.props())
// with node
def serverSideNode = serverSideWithJsEngine(Node.props())
private def serverSideWithJsEngine(jsEngine: Props) = Action.async { request =>
import akka.pattern.ask
val serverside = Play.getFile("public/javascripts/serverside.js")
implicit val timeout = Timeout(5.seconds)
val engine = Akka.system.actorOf(jsEngine, s"engine-${request.id}")
for {
data <- initialData()
result <- (engine ? Engine.ExecuteJs(
source = new File(serverside.toURI),
args = List(data),
timeout = timeout.duration
)).mapTo[JsExecutionResult]
} yield {
Ok(views.html.index(Html(new String(result.output.toArray, "UTF-8"))))
}
}
def serverSideStream = Action { request =>
import akka.pattern.ask
import ui.HtmlStreamImplicits._
val serverside = Play.getFile("public/javascripts/serverside.js")
implicit val timeout = Timeout(5.seconds)
val engine = Akka.system.actorOf(Trireme.props(), s"engine-${request.id}")
val prerendererHtml = for {
data <- initialData()
result <- (engine ? Engine.ExecuteJs(
source = new File(serverside.toURI),
args = List(data),
timeout = timeout.duration
)).mapTo[JsExecutionResult]
} yield {
Html(new String(result.output.toArray, "UTF-8"))
}
val prerendererHtmlStream = HtmlStream(prerendererHtml)
Ok.chunked(views.stream.main(prerendererHtmlStream))
}
}