So I have a webworker:
package pWorker
import scala.scalajs.js._
import org.scalajs.dom._
object WorkScript extends scala.scalajs.js.JSApp
{
def main(): Unit =
{
val x = 4
val y = 8
val z = x + y
println("Worker x + y =" -- z.toString)
}
}
When launched from the primary JavaScript thread the worker prints to the console as desired. But I can't find a way to call the equivalents of:
self.addEventListener('message', function(e) {}
self.postMessage(e.data);
that I would call from a straight Javascript file.
As always in Scala.js, if you do not find existing types for a JavaScript API, you have the option to go with dynamic types or to write your own.
Dynamic types
val self = js.Dynamic.global
self.addEventListener("message", { (e: dom.MessageEvent) =>
...
}
self.postMessage(someData)
Static types
#js.native
object WorkerGlobal extends js.GlobalScope {
def addEventListener(`type`: String, f: js.Function): Unit = js.native
def postMessage(data: js.Any): Unit = js.native
}
WorkerGlobal.addEventListener("message", { (e: dom.MessageEvent) =>
...
}
WorkerGlobal.postMessage(someData)
Related
I'm trying implement section 17.9 Workers in Scala by Example book with Scala version 2.11.7.
Import statements:
import scala.concurrent._, scala.concurrent.ops._
was error "ops not is member of scala.concurrent". I did google and known that concurrent.ops is deprecated and rather by future, change import statement to:
import scala.concurrent._, scala.concurrent.Future._
Entire class source:
import scala.concurrent._
import scala.concurrent.Future._
class ComputeServer(n: Int) {
private abstract class Job {
type T
def task: T
def res(x: T)
}
private val openJobs = new Channel[Job]()
private def processor(i: Int) {
while(true) {
val job = openJobs.read
job.res(job.task)
}
}
def future[A](p: => A): () => A = {
val reply = new SyncVar[A]()
openJobs.write{
new Job{
type T = A
def task = p
def res(x: A) = reply.put(x)
}
}
() => reply.get
}
spawn(replicate(0, n){processor})
}
But occurs errors in line: spawn(replicate(0, n){processor})
not found: value spawn
not found: value replicate
missing arguments for method processor in class ComputeServer; follow this method with `_' if you want to treat it as a partially applied function
What're spawn, replicate, processor function in version 2.11.7?
one can create method spawn like this:
def spawn(p: => Unit) {
val t = new Thread() { override def run() = p }
t.start()
}
There is some data that I have pulled from a remote API, for which I use a Future-style interface. The data is structured as a linked-list. A relevant example data container is shown below.
case class Data(information: Int) {
def hasNext: Boolean = ??? // Implemented
def next: Future[Data] = ??? // Implemented
}
Now I'm interested in adding some functionality to the data class, such as map, foreach, reduce, etc. To do so I want to implement some form of IterableLike such that it inherets these methods.
Given below is the trait Data may extend, such that it gets this property.
trait AsyncIterable[+T]
extends IterableLike[Future[T], AsyncIterable[T]]
{
def hasNext : Boolean
def next : Future[T]
// How to implement?
override def iterator: Iterator[Future[T]] = ???
override protected[this] def newBuilder: mutable.Builder[Future[T], AsyncIterable[T]] = ???
override def seq: TraversableOnce[Future[T]] = ???
}
It should be a non-blocking implementation, which when acted on, starts requesting the next data from the remote data source.
It is then possible to do cool stuff such as
case class Data(information: Int) extends AsyncIterable[Data]
val data = Data(1) // And more, of course
// Asynchronously print all the information.
data.foreach(data => println(data.information))
It is also acceptable for the interface to be different. But the result should in some way represent asynchronous iteration over the collection. Preferably in a way that is familiar to developers, as it will be part of an (open source) library.
In production I would use one of following:
Akka Streams
Reactive Extensions
For private tests I would implement something similar to following.
(Explanations are below)
I have modified a little bit your Data:
abstract class AsyncIterator[T] extends Iterator[Future[T]] {
def hasNext: Boolean
def next(): Future[T]
}
For it we can implement this Iterable:
class AsyncIterable[T](sourceIterator: AsyncIterator[T])
extends IterableLike[Future[T], AsyncIterable[T]]
{
private def stream(): Stream[Future[T]] =
if(sourceIterator.hasNext) {sourceIterator.next #:: stream()} else {Stream.empty}
val asStream = stream()
override def iterator = asStream.iterator
override def seq = asStream.seq
override protected[this] def newBuilder = throw new UnsupportedOperationException()
}
And if see it in action using following code:
object Example extends App {
val source = "Hello World!";
val iterator1 = new DelayedIterator[Char](100L, source.toCharArray)
new AsyncIterable(iterator1).foreach(_.foreach(print)) //prints 1 char per 100 ms
pause(2000L)
val iterator2 = new DelayedIterator[String](100L, source.toCharArray.map(_.toString))
new AsyncIterable(iterator2).reduceLeft((fl: Future[String], fr) =>
for(l <- fl; r <- fr) yield {println(s"$l+$r"); l + r}) //prints 1 line per 100 ms
pause(2000L)
def pause(duration: Long) = {println("->"); Thread.sleep(duration); println("\n<-")}
}
class DelayedIterator[T](delay: Long, data: Seq[T]) extends AsyncIterator[T] {
private val dataIterator = data.iterator
private var nextTime = System.currentTimeMillis() + delay
override def hasNext = dataIterator.hasNext
override def next = {
val thisTime = math.max(System.currentTimeMillis(), nextTime)
val thisValue = dataIterator.next()
nextTime = thisTime + delay
Future {
val now = System.currentTimeMillis()
if(thisTime > now) Thread.sleep(thisTime - now) //Your implementation will be better
thisValue
}
}
}
Explanation
AsyncIterable uses Stream because it's calculated lazily and it's simple.
Pros:
simplicity
multiple calls to iterator and seq methods return same iterable with all items.
Cons:
could lead to memory overflow because stream keeps all prevously obtained values.
first value is eagerly gotten during creation of AsyncIterable
DelayedIterator is very simplistic implementation of AsyncIterator, don't blame me for quick and dirty code here.
It's still strange for me to see synchronous hasNext and asynchronous next()
Using Twitter Spool I've implemented a working example.
To implement spool I modified the example in the documentation.
import com.twitter.concurrent.Spool
import com.twitter.util.{Await, Return, Promise}
import scala.concurrent.{ExecutionContext, Future}
trait AsyncIterable[+T <: AsyncIterable[T]] { self : T =>
def hasNext : Boolean
def next : Future[T]
def spool(implicit ec: ExecutionContext) : Spool[T] = {
def fill(currentPage: Future[T], rest: Promise[Spool[T]]) {
currentPage foreach { cPage =>
if(hasNext) {
val nextSpool = new Promise[Spool[T]]
rest() = Return(cPage *:: nextSpool)
fill(next, nextSpool)
} else {
val emptySpool = new Promise[Spool[T]]
emptySpool() = Return(Spool.empty[T])
rest() = Return(cPage *:: emptySpool)
}
}
}
val rest = new Promise[Spool[T]]
if(hasNext) {
fill(next, rest)
} else {
rest() = Return(Spool.empty[T])
}
self *:: rest
}
}
Data is the same as before, and now we can use it.
// Cool stuff
implicit val ec = scala.concurrent.ExecutionContext.global
val data = Data(1) // And others
// Print all the information asynchronously
val fut = data.spool.foreach(data => println(data.information))
Await.ready(fut)
It will trow an exception on the second element, because the implementation of next was not provided.
I'm looking to create a way to dynamically call logic depending on template id within scala. So template id 1 calls logic a, template id 2 call logic b, etc. The logic will be diverse but will have the same inputs/outputs. Also the number of different template ids will get into the thousands and will not be known ahead of time, so a loose coupling feels the way to go.
I've started looking at reflection to do this using scala 2.11.1 and can statically use reflection when I know the logic to be used ahead of time but have not found the correct way to dynamically use reflection, so for example passing in template id 2 will call logic b.
Below is a cut down example showing how the static version works and the skeleton I have so far for the dynamic version.
package thePackage
import scala.reflect.runtime.{universe => ru}
trait theTrait { def theMethod(x: String): Unit }
// the different logic held in different objects
object object1 extends theTrait {
def theMethod(x: String) = { println("a " + x ) }
}
object object2 extends theTrait {
def theMethod(x: String) = { println("b " + x ) }
}
object object3 extends theTrait {
def theMethod(x: String) = { println("c " + x ) }
}
// run static/dynamic reflection methods
object ReflectionTest {
// "static" invocation calling object1.theMethod
def staticInvocation() = {
val m = ru.runtimeMirror(getClass.getClassLoader)
val im = m.reflect(thePackage.object1)
val method = ru.typeOf[thePackage.object1.type]
.decl(ru.TermName("theMethod")).asMethod
val methodRun = im.reflectMethod(method)
methodRun("test")
}
staticInvocation
// "dynamic" invocation using integer to call different methods
def dynamicInvocation( y: Integer) = {
val m = ru.runtimeMirror(getClass.getClassLoader)
val module = m.staticModule("thePackage.object" + y)
val im = m.reflectModule(module)
// stuck... static approach does not work here
}
dynamicInvocation(1)
dynamicInvocation(2)
dynamicInvocation(3)
}
What needs to be added/changed to the dynamicInvocation method to make this work, or should I be using a different approach?
You need to get an instance mirror for your module, on which you can reflect the method.
def dynamicInvocation( y: Integer) = {
val m = ru.runtimeMirror(getClass.getClassLoader)
val module = m.staticModule("thePackage.object" + y)
val im = m.reflectModule(module)
val method = im.symbol.info.decl(ru.TermName("theMethod")).asMethod
val objMirror = m.reflect(im.instance)
objMirror.reflectMethod(method)("test")
}
It seems that TermName method in above solution has been replaced by newTermName and also the info.decl seems to not work. Below line worked for me
val method = im.symbol.typeSignature.member(ru.newTermName("testMethod")).asMethod
I'm trying to create a generic adapter for AsyncClient in thrift for Scala that will let an rpc implement Function1[A, Future[B]] rather than use thrift's less composable built-in callback approach. This is made challenging by the fact that the generated apis for thrift classes are largely non-generic, so creating simple generic wrapper for an arbitrary thrift client is not straightforward. Consider the following example:
class AsyncThriftClient[A, B, X](
requestConsumer: (A, AsyncMethodCallback[X]) => Unit,
callbackResultConverter: X => B) extends Function1[A, Future[B]] {
private class Callback(p: Promise[B])
extends AsyncMethodCallback[X] {
def onComplete(x: X): Unit = {
try {
val result = callbackResultConverter(x)
println("from server: " + result)
p.success(result)
} catch {
case e: Exception => p.failure(e)
}
}
def onError(e: Exception): Unit = {
p.failure(e)
}
}
def apply(request: A): Future[B] = {
val p = Promise[B]
requestConsumer(request, new Callback(p))
p.future
}
}
def main(args: Array[String]) {
try {
val ex = Executors.newSingleThreadExecutor
implicit val ec = ExecutionContext.fromExecutor(ex)
val client = new ServiceStatus.AsyncClient(
new TBinaryProtocol.Factory,
new TAsyncClientManager,
new TNonblockingSocket("localhost", 9090))
val fun = new AsyncThriftClient[ //
StatusRequest, StatusResponse, ServiceStatus.AsyncClient.status_call](
client.status(_, _),
_.getResult)
val request = new StatusRequest("say hi")
val fut = fun(request)
fut.onSuccess { case r => println(s"succ $r") }
fut.onFailure { case e => println(s"erro $e") }
Thread.sleep(1000)
ex.shutdown()
} catch {
case e: Exception => e.printStackTrace()
}
}
This seems like a reasonable first attempt, but note the type parameter X which is bound to ServiceStatus.AsyncClient.status_call. It seems like I shouldn't need to supply this because it's not important for any of the method signatures in AsyncThriftClient. What I really need is to say that there should be "some type" X such that the following constructor parameters agree, which sounds a lot like existential types. The resulting invocation site would look like the following:
val client = new ServiceStatus.AsyncClient(
new TBinaryProtocol.Factory,
new TAsyncClientManager,
new TNonblockingSocket("localhost", 9090))
val fun = new AsyncThriftClient[StatusRequest, StatusResponse](
client.status(_, _),
_.getResult)
and the compiler would figure out that there is a suitable X that lets client.status(_, _) and _.getResult match up. Is there a way to achieve this? (By the way, a follow up task is to encapsulate the instantiation of client, which would probably require a similar technique).
I would wrap the whole thing up in an abstract API proxy thing, and leave the specification of the intermediate Thrift type, and the implementation of the type translation functions, to the concrete implementation. Something like this:
trait AsyncThriftAPI[A,B] {
protected type X // Intermediate Thrift type; not for use outside API implementations
// Implementor must specify these.
protected def sendRequest(in: A, callback: AsyncMethodCallback[X]): Unit
protected def convertResult(intermediate: X): B
// Note that up here, we never use the client directly,
// so let's not needlessly couple this API proxy pattern
// to too many transport dependencies
// final because of "must be abstract or final" dogma :)
final def apply(request: A): Future[B] = {
val p = Promise[B]
sendRequest(request, new Callback(p))
p.future
}
private class Callback(p: Promise[B]) extends AsyncMethodCallback[X] {
def onComplete(x: X): Unit = {
try {
val result = convertResult(x)
println("from server: " + result)
p.success(result)
} catch {
case e: Exception => p.failure(e)
}
}
def onError(e: Exception): Unit = {
p.failure(e)
}
}
}
Now to implement it:
final class StatusAPI(implicit val transport: TNonblockingTransport,
val clientManager: TAsyncClientManager,
val protocolFactory: TProtocolFactory)
extends AsyncThriftAPI[StatusRequest, StatusResponse]
{
protected type X = ServiceStatus.AsyncClient.status_call
// Lazy so that we don't bother to spin it up until someone actually calls the API
lazy val client = new ServiceStatus.AsyncClient(protocolFactory,
clientManager,
transport)
protected def sendRequest(in: A, callback: AsyncMethodCallback[X]): Unit = client.status(in, callback)
protected def convertResult(intermediate: X) = intermediate.getResult
}
At the call site:
// Have these in scope somewhere near the root of whichever component
// needs to connect to a variety of Thrift servers
implicit val protoFactory = new TBinaryProtocol.Factory
implicit val clientManager = new TAsyncClientManager
implicit val transport = new TNonblockingSocket("localhost", 9090))
val statusApi = new StatusAPI()
statusApi(new StatusRequest(...)) // returns Future[StatusResponse]
I haven't attempted to compile this, please let me know if there are any mistakes.
If it were me I'd probably want to bundle a bunch of different, related API calls into one API proxy, so that might call for an additional layer of abstraction. :)
Having a trait
trait Persisted {
def id: Long
}
how do I implement a method that accepts an instance of any case class and returns its copy with the trait mixed in?
The signature of the method looks like:
def toPersisted[T](instance: T, id: Long): T with Persisted
This can be done with macros (that are officially a part of Scala since 2.10.0-M3). Here's a gist example of what you are looking for.
1) My macro generates a local class that inherits from the provided case class and Persisted, much like new T with Persisted would do. Then it caches its argument (to prevent multiple evaluations) and creates an instance of the created class.
2) How did I know what trees to generate? I have a simple app, parse.exe that prints the AST that results from parsing input code. So I just invoked parse class Person$Persisted1(first: String, last: String) extends Person(first, last) with Persisted, noted the output and reproduced it in my macro. parse.exe is a wrapper for scalac -Xprint:parser -Yshow-trees -Ystop-after:parser. There are different ways to explore ASTs, read more in "Metaprogramming in Scala 2.10".
3) Macro expansions can be sanity-checked if you provide -Ymacro-debug-lite as an argument to scalac. In that case all expansions will be printed out, and you'll be able to detect codegen errors faster.
edit. Updated the example for 2.10.0-M7
It is not possible to achieve what you want using vanilla scala. The problem is that the mixins like the following:
scala> class Foo
defined class Foo
scala> trait Bar
defined trait Bar
scala> val fooWithBar = new Foo with Bar
fooWithBar: Foo with Bar = $anon$1#10ef717
create a Foo with Bar mixed in, but it is not done at runtime. The compiler simply generates a new anonymous class:
scala> fooWithBar.getClass
res3: java.lang.Class[_ <: Foo] = class $anon$1
See Dynamic mixin in Scala - is it possible? for more info.
What you are trying to do is known as record concatenation, something that Scala's type system does not support. (Fwiw, there exist type systems - such as this and this - that provide this feature.)
I think type classes might fit your use case, but I cannot tell for sure as the question doesn't provide sufficient information on what problem you are trying to solve.
Update
You can find an up to date working solution, which utilizes a Toolboxes API of Scala 2.10.0-RC1 as part of SORM project.
The following solution is based on the Scala 2.10.0-M3 reflection API and Scala Interpreter. It dynamically creates and caches classes inheriting from the original case classes with the trait mixed in. Thanks to caching at maximum this solution should dynamically create only one class for each original case class and reuse it later.
Since the new reflection API isn't that much disclosed nor is it stable and there are no tutorials on it yet this solution may involve some stupid repitative actions and quirks.
The following code was tested with Scala 2.10.0-M3.
1. Persisted.scala
The trait to be mixed in. Please note that I've changed it a bit due to updates in my program
trait Persisted {
def key: String
}
2. PersistedEnabler.scala
The actual worker object
import tools.nsc.interpreter.IMain
import tools.nsc._
import reflect.mirror._
object PersistedEnabler {
def toPersisted[T <: AnyRef](instance: T, key: String)
(implicit instanceTag: TypeTag[T]): T with Persisted = {
val args = {
val valuesMap = propertyValuesMap(instance)
key ::
methodParams(constructors(instanceTag.tpe).head.typeSignature)
.map(_.name.decoded.trim)
.map(valuesMap(_))
}
persistedClass(instanceTag)
.getConstructors.head
.newInstance(args.asInstanceOf[List[Object]]: _*)
.asInstanceOf[T with Persisted]
}
private val persistedClassCache =
collection.mutable.Map[TypeTag[_], Class[_]]()
private def persistedClass[T](tag: TypeTag[T]): Class[T with Persisted] = {
if (persistedClassCache.contains(tag))
persistedClassCache(tag).asInstanceOf[Class[T with Persisted]]
else {
val name = generateName()
val code = {
val sourceParams =
methodParams(constructors(tag.tpe).head.typeSignature)
val newParamsList = {
def paramDeclaration(s: Symbol): String =
s.name.decoded + ": " + s.typeSignature.toString
"val key: String" :: sourceParams.map(paramDeclaration) mkString ", "
}
val sourceParamsList =
sourceParams.map(_.name.decoded).mkString(", ")
val copyMethodParamsList =
sourceParams.map(s => s.name.decoded + ": " + s.typeSignature.toString + " = " + s.name.decoded).mkString(", ")
val copyInstantiationParamsList =
"key" :: sourceParams.map(_.name.decoded) mkString ", "
"""
class """ + name + """(""" + newParamsList + """)
extends """ + tag.sym.fullName + """(""" + sourceParamsList + """)
with """ + typeTag[Persisted].sym.fullName + """ {
override def copy(""" + copyMethodParamsList + """) =
new """ + name + """(""" + copyInstantiationParamsList + """)
}
"""
}
interpreter.compileString(code)
val c =
interpreter.classLoader.findClass(name)
.asInstanceOf[Class[T with Persisted]]
interpreter.reset()
persistedClassCache(tag) = c
c
}
}
private lazy val interpreter = {
val settings = new Settings()
settings.usejavacp.value = true
new IMain(settings, new NewLinePrintWriter(new ConsoleWriter, true))
}
private var generateNameCounter = 0l
private def generateName() = synchronized {
generateNameCounter += 1
"PersistedAnonymous" + generateNameCounter.toString
}
// REFLECTION HELPERS
private def propertyNames(t: Type) =
t.members.filter(m => !m.isMethod && m.isTerm).map(_.name.decoded.trim)
private def propertyValuesMap[T <: AnyRef](instance: T) = {
val t = typeOfInstance(instance)
propertyNames(t)
.map(n => n -> invoke(instance, t.member(newTermName(n)))())
.toMap
}
private type MethodType = {def params: List[Symbol]; def resultType: Type}
private def methodParams(t: Type): List[Symbol] =
t.asInstanceOf[MethodType].params
private def methodResultType(t: Type): Type =
t.asInstanceOf[MethodType].resultType
private def constructors(t: Type): Iterable[Symbol] =
t.members.filter(_.kind == "constructor")
private def fullyQualifiedName(s: Symbol): String = {
def symbolsTree(s: Symbol): List[Symbol] =
if (s.enclosingTopLevelClass != s)
s :: symbolsTree(s.enclosingTopLevelClass)
else if (s.enclosingPackageClass != s)
s :: symbolsTree(s.enclosingPackageClass)
else
Nil
symbolsTree(s)
.reverseMap(_.name.decoded)
.drop(1)
.mkString(".")
}
}
3. Sandbox.scala
The test app
import PersistedEnabler._
object Sandbox extends App {
case class Artist(name: String, genres: Set[Genre])
case class Genre(name: String)
val artist = Artist("Nirvana", Set(Genre("rock"), Genre("grunge")))
val persisted = toPersisted(artist, "some-key")
assert(persisted.isInstanceOf[Persisted])
assert(persisted.isInstanceOf[Artist])
assert(persisted.key == "some-key")
assert(persisted.name == "Nirvana")
assert(persisted == artist) // an interesting and useful effect
val copy = persisted.copy(name = "Puddle of Mudd")
assert(copy.isInstanceOf[Persisted])
assert(copy.isInstanceOf[Artist])
// the only problem: compiler thinks that `copy` does not implement `Persisted`, so to access `key` we have to specify it manually:
assert(copy.asInstanceOf[Artist with Persisted].key == "some-key")
assert(copy.name == "Puddle of Mudd")
assert(copy != persisted)
}
While it's not possible to compose an object AFTER it's creation, you can have very wide tests to determine if the object is of a specific composition using type aliases and definition structs:
type Persisted = { def id: Long }
class Person {
def id: Long = 5
def name = "dude"
}
def persist(obj: Persisted) = {
obj.id
}
persist(new Person)
Any object with a def id:Long will qualify as Persisted.
Achieving what I THINK you are trying to do is possible with implicit conversions:
object Persistable {
type Compatible = { def id: Long }
implicit def obj2persistable(obj: Compatible) = new Persistable(obj)
}
class Persistable(val obj: Persistable.Compatible) {
def persist() = println("Persisting: " + obj.id)
}
import Persistable.obj2persistable
new Person().persist()