akka-js / akka.js Goto Github PK
View Code? Open in Web Editor NEWAkka, for Scala.js
Home Page: http://akka-js.org
Akka, for Scala.js
Home Page: http://akka-js.org
Hi, when you write a communication mechanism that allows WebWorkers to talk to each other, watch out for communication that would require opaque objects to be transferred. I can't use the scalajs-rx-idb library because it uses lihaoi's upickle which transforms everything to a string . See l15k4/scalajs-rx-idb#3
Implement timeout in akka.concurrent.Await
We must follow Akka ones where presents and do not diverge from the original signatures as highlighted in #43
Do you have a gitter channel to discuss things?
actor/
dispatch/
event/
pattern/
routing/
serialization/
util/
context
by rewriting IR in ActorCell.scala
akka.util.JS*
akka-remote
)typesafe.config.Config
(it's 100% Java, so we can't cross-compile. alternatives? see @mfirry 's suggestion in #5 )sun.misc.Unsafe
(stub implementation vs mixin with traits JS/JVM specific methods?)JSMap
to TreeMap
System.getEnv
and System.getProperty
calls to remove (eg: ActorSystem.scala
)mailboxTypes
are missingThread.currentThread().interrupt()
)event/
(and therefore Logging)setActorFields
in Actor.scala
ThreadLocal
, etc) from ActorCell.scala
and add lookupAndSetField
ActorRefProvider.scala
override def
in the EventLoopScheduler
(they override final methods, had to fix by hand)dispatch/AbstractDispatcher.scala
contains some thread-specific logic, refactor it out?Currently blocked by:
Any
(scala pickling should help solve the issue: @phaller @heathermiller )Hi,
is this library could be used in node.js and programming be done using JavaScript or TypeScript instead of scala.js?
As I imagine it would be possible to do require('akka.js') and use its facilities.
I've downloaded a latest release, but cannot find any file like "akka.js"
Would be possible to export this library to npm package?
There are a few constructs in akka http that are quite high level and don't depend on a lot of the streaming stuff such as the Akka.http.model.Uri which I ported a year ago and all of the header parsing code. Those I think could already be very useful for everyday scala.js http development.
Like we did for Logs we need to realize if this is feasible or have an acceptable alternative that can be pushed back to akka master
call stack size exceeded
[error] TypeError: Cannot read property 'prototype' of undefined
[error] at $newJSObjectWithVarargs([stdin]:497:45)
[error] at akka.actor.JsReflectable$class.instantiate([stdin]:2191:15)
[error] at akka.actor.NoArgsReflectConstructor.produce([stdin]:34630:32)
[error] at akka.actor.ActorCell.newActor([stdin]:73305:77)
[error] at akka.actor.ActorCell.create([stdin]:73243:24)
[error] at akka.actor.ActorCell.invokeAll$1([stdin]:73439:18)
[error] at akka.actor.ActorCell.systemInvoke([stdin]:73197:8)
[error] at akka.dispatch.Mailbox.processAllSystemMessages([stdin]:35141:18)
[error] at akka.dispatch.Mailbox.run([stdin]:35091:12)
[error] at {anonymous}()([stdin]:34967:19)
It cannot instantiate because it is a nested class (@JSExport doesn't work)
Has the project considered support networking features through Node with https://github.com/scalajs-io/scalajs.io?
Avoid the commits of generated files and reproduce akka build chain to use sbt-boilerplate directly.
Some data structures, which are heavily used in Akka, are currently missing in Akka.js/Scala.js
Most notably:
java.util.TreeSet
java.util.Locale
java.util.ConcurrentHashMap
java.util.ConcurrentSkipListSet
akka.util.Index
(mutable.HashMap with mutable.MultiMap
is enough for this, we need a generic Index
to be implemented in JS/JVM code)java.net.MalformedUrlException
java.util.AbstractQueue
java.util.Queue
java.util.LinkedList
java.util.concurrent.atomic.AtomicArrayReference
java.util.concurrent.CopyOnWriteArrayList
java.util.concurrent.ConcurrentLinkedQueue
java.util.PriorityQueue
java.util.Deque
To allow for 100% Java interoperability we should also implement the DS' supertypes, but it's a pretty big task, maybe we could just do with the basic methods for now?
Akka.JVM uses (I'm assuming for performance reasons) some JVM data structures, which are not available in Scala-js (eg: Deque
)
Akka currently only uses a small subset of methods from each class.
There are two ways we can fix this: either we completely port the required data structures to Scala-js OR we can do something like this:
in jvm/src/main/akka/util/
class AkkaDeque[A] extends Deque[V] {
def methodWeNeed = threadLocalMethod()
}
in js/src/main/akka/util/
class AkkaDeque[A] {
var value: A = _
def methodWeNeed = ???
}
On one hand, solution 1 requires a lot of effort on the Scala-js side, but it doesn't require any changes to Akka itself.
On the other hand, solution 2 would require some changes and it might be a bit more clumsy in case you need new methods from the underlying collection (you need to manually add the method to AkkaDeque
), but it doesn't require nearly as much effort on the Scala-js side
Thoughts?
When I try to run my Scala.js tests (that work with Akka on the JVM) I'm getting the following at fast opt:
[error] Referring to non-existent method scala.concurrent.impl.Promise$CompletionLatch.releaseShared(scala.Int)scala.Boolean
[error] called from scala.concurrent.impl.Promise$CompletionLatch.apply(scala.util.Try)scala.Unit
[error] called from scala.concurrent.impl.Promise$CompletionLatch.apply(java.lang.Object)java.lang.Object
[error] called from scala.Function1.apply$mcVD$sp(scala.Double)scala.Unit
[error] called from scala.collection.AbstractSeq.apply$mcVD$sp(scala.Double)scala.Unit
Is there something I'm doing wrong or is this a missing feature?
Minor issue.
In the common settings the use of EclipseKeys
means that sbt
won't run on my system. I suppose one has to import them somewhere else. I use IntelliJ.
Removing the two lines gets it to work
--- a/build.sbt
+++ b/build.sbt
@@ -1,6 +1,6 @@
val commonSettings = Seq(
- EclipseKeys.useProjectId := true,
- EclipseKeys.skipParents in ThisBuild := false,
+// EclipseKeys.useProjectId := true,
+// EclipseKeys.skipParents in ThisBuild := false,
Props[Typename]Does not work when the class is in a module (must be top level) must rewrite to
Props[new Typename(…)]```
Typesafe Config
akka
akka.actor.dispatch
7. ExecutionContextSpec.scala
akka.pattern
8. PatternSpec
akka.routing
11. BalancingSpec
akka.event
14. AddressTerminatedTopicBenchSpec
akka.stream.impl
akka.stream
2. akka.stream.scaladsl.SubstreamSubscriptionTimeoutSpec
Right now we do not have a check of uniqueness of extensions.
This could be done with a WeakMap[ActorSystem, HashMap[ExtensionName, ExtensionInstance]]
just TBD
For discussion:
the project reactive-stream-scalajs provides only few interfaces to be implemented.
Since here they say there are problems publishing the project I think we can simply include the related sources into the akka-stream-js project without having it as a dependency.
This will be an hook for future reference on decisions taken about the reliable reuse of Akka sources.
We have different kind of problems and we get to face them differently:
1- Semantic differences:
if in a file there are implementations that do not conform to js-vm semantics we will split implementations and interfaces in different files, use just the interfaces and PR the modification to upstream Akka.
2- Java API:
Since it is hard-wired into interfaces it will be dropped at compile time via a compiler plugin (basically we remove the related AST based on configuration files)
3- Scala.Js needed annotations:
We will apply them between typer and jsinterop using a compiler plugin
4- Inner class substitutions:
In order to save the huge amount of code on some singletons(i.e. ActorSystem) we will replace inner classes after the parser based on a config file.
5- context
reflection workaround:
Actor context
field is subject to reflection hacking to keep developer Api clean, the bheaviour could be replicated manipulating the IR (as suggested by @sjrd https://github.com/sjrd/scala-js-example-app/tree/hack-set-val)
Hope this will cover 100% of the use cases.
Ideas or suggestions that will simplify this huge work are very much welcome!
right now assembleAkkaLibrary
is entirely defined every time.
We need to factor it out to keep it easier to use and debug in case.
Though I will not expect running a HTTP server on Scala.js, some data structures from akka-http like Path
and Uri
are useful in Scala.js .
Another usage of akka-http.js is creating an in-memory mock server to handler fake HTTP requests (for testing purpose).
I'm getting an error just starting up an ActorSystem.
Referring to non-existant method java.text.SimpleDateFormat.format(java.util.Date)
called from akka.event.Logging...timestamp(...)
Using scalajs 0.6.14 and akkajs 0.2.4.16
Most of the code can be shared between Akka.JVM and Akka.js so my proposal is, for akka-actor
, to adopt the standard layout of cross-compilable Scala-js modules which is the following
shared/
directory with shared codejs/
directory with JS specific implementationsjvm/
directory with JVM specific implementationsin ActorSystem.scala
I ported my application to use akka.js
and found an increase of size from 251KB
to 394KB
.
The original application produces the following files with fullOptJs
-rw-r--r-- 1 hjs staff 1.0M 20 Jun 17:18 rww-scala-js-opt.js
-rw-r--r-- 1 hjs staff 251K 20 Jun 17:18 rww-scala-js-opt.js.gz
whereas my ported application produces this:
-rw-r--r-- 1 hjs staff 1.6M 20 Jun 15:24 rww-scala-js-opt.js
-rw-r--r-- 1 hjs staff 394K 20 Jun 15:24 rww-scala-js-opt.js.gz
Is this due to the weak typing of actors as Any => Unit
?
Using scala.js linker we can for example register classes of actors to be loaded at runtime.
starting from a clean install ( and after removing the Eclipse plugins ) if I try to run package I
get the errors below. I tried compiling scalatest-2.3x but that produced differents jars such as .ivy2/local/org.scalatest/scalatest_2.11/3.0.0-M1/bundles/scalatest_2.11.jar
- eg no scalatestjs
but just scalatest
. Using those did not help.
> clean
[success] Total time: 0 s, completed 16-Jun-2015 18:44:21
> package
[info] Updating {file:/Volumes/Dev/Programming/ScalaJS/akka.js/}root...
[info] Updating {file:/Volumes/Dev/Programming/ScalaJS/akka.js/}akkaActorJS...
[info] Resolving org.scalatest#scalatestjs_sjs0.6_2.11;2.3.0-SNAP2 ...
[warn] module not found: org.scalatest#scalatestjs_sjs0.6_2.11;2.3.0-SNAP2
[warn] ==== local: tried
[warn] /Users/hjs/.ivy2/local/org.scalatest/scalatestjs_sjs0.6_2.11/2.3.0-SNAP2/ivys/ivy.xml
[warn] ==== public: tried
[warn] https://repo1.maven.org/maven2/org/scalatest/scalatestjs_sjs0.6_2.11/2.3.0-SNAP2/scalatestjs_sjs0.6_2.11-2.3.0-SNAP2.pom
[warn] ==== Typesafe repository: tried
[warn] http://repo.typesafe.com/typesafe/releases/org/scalatest/scalatestjs_sjs0.6_2.11/2.3.0-SNAP2/scalatestjs_sjs0.6_2.11-2.3.0-SNAP2.pom
[warn] ==== sonatype-snapshots: tried
[warn] https://oss.sonatype.org/content/repositories/snapshots/org/scalatest/scalatestjs_sjs0.6_2.11/2.3.0-SNAP2/scalatestjs_sjs0.6_2.11-2.3.0-SNAP2.pom
[info] Resolving org.eclipse.jetty#jetty-continuation;8.1.16.v20140903 ...
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: org.scalatest#scalatestjs_sjs0.6_2.11;2.3.0-SNAP2: not found
It would be helpful to have a SNAPSHOT release so that I could mere rww-scala-js actor branch into the main branch.
Due to enable GC works properly we need to reshape Unsafe HashMap in something like:
WeakMap[ObjectRef, HashMap[Int, Any]].
this should be easy, it needs the implementation of some methods within our akka.util.Unsafe
, probably a little bit of copy paste should do the trick ;-)
The build is already configured within the branch typed
Some parts of Akka.JVM are designed to be run synchronously, but unfortunately we cannot block in JS.
For instance, some points that come to mind
TestKit is the toughest one because it really is 100% blocking. So far I've been able to make it work by using a custom event loop which is able to block, but I wouldn't call it a reliable solution. Ideally the test suite should be refactored to use futures.
I do understand however this is a huge undertaking
Integrate download of akka sources using jgit as scala.js and scala-native do.
To reproduce change the last line in the Run.run in the stream demo class to
Streams.complexFlow(true)
This causes the val toStringActorPublisherSource in method Streams.complexFlow to be assigned to the expression Source.actorPublisher[String](Props[ToStringActorPublisher])
Exception stack trace below
ERROR] [Tue Jul 22:13:42 GMT+0100 2016] [main] [akka://streams/user/StreamSupervisor-1/flow-1-1-actorPublisherSource] null akka.actor.ActorInitializationException: akka://streams/user/StreamSupervisor-1/flow-1-1-actorPublisherSource: exception during creation at $c_Lakka_actor_ActorInitializationException.$c_jl_Throwable.fillInStackTrace__jl_Throwable(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:27427:14) at $c_Lakka_actor_ActorInitializationException.$c_jl_Throwable.init___T__jl_Throwable(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:27516:8) at akka.actor.ActorInitializationException.<init>(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:63826:52) at akka.actor.ActorCell.create(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:78844:69) at akka.actor.ActorCell.invokeAll$1(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:78895:18) at $c_Lakka_dispatch_Dispatcher$$anon$1.$c_Lakka_dispatch_Mailbox.processAllSystemMessages__V(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:30826:12) at $c_Lakka_dispatch_Dispatcher$$anon$1.$c_Lakka_dispatch_Mailbox.run__V(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:30776:12) at null._onTimeout(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:30653:19) at Timer.listOnTimeout(timers.js:119:15) Caused by: TypeError: Cannot read property 'prototype' of undefined at $newJSObjectWithVarargs(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:449:45) at akka.util.Reflect$.instantiate(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:13835:12) at akka.util.Reflect$.instantiate(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:13848:17) at akka.actor.NoArgsReflectConstructor.produce(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:21589:57) at akka.actor.ActorCell.newActor(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:79009:73) at akka.actor.ActorCell.create(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:78814:24) at akka.actor.ActorCell.invokeAll$1(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:78895:18) at $c_Lakka_dispatch_Dispatcher$$anon$1.$c_Lakka_dispatch_Mailbox.processAllSystemMessages__V(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:30826:12) at $c_Lakka_dispatch_Dispatcher$$anon$1.$c_Lakka_dispatch_Mailbox.run__V(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:30776:12) at null._onTimeout(/Users/solomono/Development/Repository/Git/akka.js-fork/akka-stream-demo/js/target/scala-2.11/demo-fastopt.js:30653:19)
I'm collecting some potential use cases for akka.js, if anyone has ideas please do feel free to contribute!
In this example we have multiple clients (browsers) on which an actor system is running and for each actor system 1-n actors taking care of the UI of the chat. Communication would be done through akka-remote
with WebRTC as a transport layer.
The interesting part here is that the existing Akka infrastructure for message delivery can be leveraged to allow the programmer to be completely oblivious about the inner workings of WebRTC
In this example we have an Actor which is listening for DOM events and reacts to them. By composing actor behaviour and encapsulate each element's status inside an actor, we can create reactive dead-simple UIs.
This approach is interesting because it frees the programmer from the constraints of the DOM model and could potentially be a platform on top of which one can build DOM optimizations (diff'ing etc)
example:
https://github.com/unicredit/akka.js-examples/tree/master/calculator
In this example we have two projects: a Scala one ("server.scala") and a client one ("client.scala"). Once they are compiled they run in their respective environments (JVM for Akka.JVM, JS VM for Akka.js) but they can still communicate transparently through WebSockets.
This is interesting because it would allow to use one single abstraction for all communications, in a sense it's the complementary of what Play already does in handling WebSockets with Akka actors in the backend.
In this example we have a code ("algorithm.scala") implementing an algorithm which runs on a JVM backend ("SERVER"), but which if need be, can also run in the frontend through Akka.js. A visualization interface can easily be built which plugs into the algorithm in a step-by-step fashion and shows each step, thus making the explanation much easier.
The interesting thing is, we could leverage all the existing algorithms already implemented in Akka!
example:
https://github.com/unicredit/akka.js-examples/tree/master/raft
JS has historically being a single threaded language and it remains so to this date, however Web Workers provide a way for the "main" thread to spawn more JS VMs and interact with them through message passing. This mechanism allows to perform heavy computation off the UI thread which is thus still responsive to user events.
Unfortunately the message passing API only supports few data structures and Akka.js (through it's built-in serialization) would be able to make working with Web Workers a much more seamless experience. It could also potentially evolve into an optimization if the serialization were to be done into ArrayBuffers which are then sent as Transferable Objects
I think that the idea behind these projects is that a higher level abstraction in the browser, combined with Akka's maturity would open up doors to a bunch of new applications which were previously very cumbersome to develop in vanilla JS
In case you have any questions about the above, please do feel free to ask :D
We need to implement this interface since it's heavily used in Akka internally, especially in the various Configurator
Playing around with akka.js at https://scalafiddle.io I noticed a problem with actor instantiation.
This one works fine. Link to fiddle: https://scalafiddle.io/sf/h8XVHMe/0
import akka.actor._
object ShoutBox {
def props: Props = Props(new ShoutBox)
}
final class ShoutBox extends Actor {
override def receive: Receive = {
case x: String => println(x.toUpperCase)
}
}
val system = ActorSystem()
val shout = system.actorOf(ShoutBox.props)
println("Shoutbox created")
shout ! "hello"
shout ! "world"
This one doesn't work. Link to fiddle: https://scalafiddle.io/sf/luBGLkI/1
import akka.actor._
object ShoutBox {
def props: Props = Props(classOf[ShoutBox])
}
final class ShoutBox extends Actor {
override def receive: Receive = {
case x: String => println(x.toUpperCase)
}
}
val system = ActorSystem()
val shout = system.actorOf(ShoutBox.props)
println("Shoutbox created")
shout ! "hello"
shout ! "world"
Can somebody clarify, is this behaviour right, or both ways should work?
Thanks to @solomono we get a great number of tests that already work.
Unfortunately they diverge from akka original sources and this force us to manually realign things.
This is bad an not affordable in the slices of time where akka.js is developed.
At the moment I'm going to evict every failure test but I need a better solution for the future.
find a way to provide a default meaningful configuration that let user use ActorSystem("name") without providing the custom one.
The only missing feature of Akka respect Erlang is dynamic code change.
JS is a very dynamic VM and re-evaluating code using eval
could do the trick.
This should be explored.
After a POC stripping down the code to be reloaded to a single actor behavior should be evaluated.
There are many pickling libs and scalajs-pickling is definitely not the best one. I suggest to make websocket implementation pickler-agnostic (like it is with autowire) so people will be able to choose favourite pickling libs, like BooPickler, Prickle, UPickler and so on.
ScalaPB seems to be available on both platforms, probably we can dig a bit on usign Protobuf for messages exchange.
we need first to port to scala.js
should be fun :-)
typesafe.config.Config is written in Java, aka no cross compile.. gotta figure out what to do
https://beetta.scalafiddle.io/sf/t9S8d6/0
import fiddle.Fiddle, Fiddle.println
import akka.actor.ActorSystem
import akka.stream._
import akka.stream.scaladsl._
import akka.stream.stage.{GraphStage, GraphStageLogic, InHandler}
implicit val system = ActorSystem("pi")
implicit val dispatcher = system.dispatcher
implicit val materializer = ActorMaterializer()
final class PrintlnSink(prefix: String) extends GraphStage[SinkShape[Any]] {
val in = Inlet[Any]("PrintlnSink.in")
override def shape = SinkShape(in)
override def createLogic(inheritedAttributes: Attributes) =
new GraphStageLogic(shape) {
// a new GraphStageLogic will be created each time we materialize the sink
// so all state that we want to keep for the stage should be withing the logic.
//
// here we maintain a counter of
private var count = 0L
setHandler(in, new InHandler {
/**
* Called when the input port has a new element available.
* The actual element can be retrieved via the [[GraphStageLogic.grab()]] method.
*/
override def onPush(): Unit = {
val element = grab(in)
count += 1 // the GraphStage maintains the Actor-like single-threaded illusion
println(s"[$prefix:$count] $element")
pull(in)
}
})
// we start the flow of data by an initial pull
pull(in)
}
}
Source(1 to 10).runWith(new PrintlnSink("hello"))
Blows up with ERROR: Cannot read property 'portState$1' of null
We could @JSExport
some functions to provide entry point from JS, this would allow to use akka.js from JS and other JS-compiled languages
Documentation or examples should show how to use the basic config with a single value override. Like set the loglevel to WARN. Would be nice to see that in documentation. The examples only show parsing a full config from a string.
ConfigFactory.load() doesn't work.
It seems that Logging loading is changed and custom loggers are not loaded.
Not sure if this refer to the entier configuration...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.