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()
}
Related
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)
I am trying to test a simple application in Scala , and test it with PowerMock.
Below is my code
Service.scala
trait Service {
def getName(): String
def start(): Int
}
ServiceListener.scala
trait ServiceListener {
def onSuccess(service: Service): Unit
def onFailure(service: Service): Unit
}
SomeSystem.scala
import java.util
import java.util.List
import SomeSystem._
import scala.collection.JavaConversions._
object SomeSystem {
def notifyServiceListener(serviceListener: ServiceListener, service: Service, success: Boolean) {
if (serviceListener != null) {
if (success) {
serviceListener.onSuccess(service)
} else {
serviceListener.onFailure(service)
}
}
}
def startServiceStaticWay(service: Service): Int = {
val returnCode = service.start()
returnCode
}
}
class SomeSystem {
private val services: List[Service] = new util.ArrayList[Service]()
private var serviceListener: ServiceListener = _
private val events: List[String] = new util.ArrayList[String]()
def start() {
for (service <- services) {
val something = startServiceStaticWay(service)
val success = something > 0
notifyServiceListener(serviceListener, service, success)
addEvent(service, success)
}
}
private def addEvent(service: Service, success: Boolean) {
events.add(getEvent(service.getName, success))
}
private def getEvent(serviceName: String, success: Boolean): String = {
serviceName + (if (success) "started" else "failed")
}
def add(someService: Service) {
services.add(someService)
}
def setServiceListener(serviceListener: ServiceListener) {
this.serviceListener = serviceListener
}
}
I am trying to unit test SomeSystem.scala as below
import {ServiceListener, SomeSystem, Service}
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito
import org.powermock.api.mockito.PowerMockito
import org.powermock.modules.junit4.PowerMockRunner
//remove if not needed
import scala.collection.JavaConversions._
#RunWith(classOf[PowerMockRunner])
class PowerMockitoIntegrationTest {
private var service: Service = _
private var system: SomeSystem = _
private var serviceListener: ServiceListener = _
#Before
def setupMock() {
service = Mockito.mock(classOf[Service])
serviceListener = Mockito.mock(classOf[ServiceListener])
system = Mockito.spy(new SomeSystem())
system.add(service)
system.setServiceListener(serviceListener)
}
#Test
def startSystem() {
p("Stub using PowerMockito. service.start() should return 1 as we want start of the service to be successful")
PowerMockito.when(service.start()).thenReturn(1)
p("Start the system, should start the services in turn")
system.start()
p("Verify using Mockito that service started successfuly")
Mockito.verify(serviceListener).onSuccess(service)
p("Verifed. Service started successfully")
}
private def p(s: String) {
println(s)
}
}
Unfortunately I am getting the below compilation error , I am confused why it is appearing and any way we could do get rid of it.
[ERROR] C:\IntellJWorkspace\PowerMockProblem\src\test\scala\PowerMockitoIntegrationTest.scala:29: error: ambiguous reference to overloaded definition,
[ERROR] both method when in object PowerMockito of type [T](x$1: T)org.mockito.stubbing.OngoingStubbing[T]
[ERROR] and method when in object PowerMockito of type [T](x$1: Any, x$2: Object*)org.mockito.stubbing.OngoingStubbing[T]
[ERROR] match argument types (Int)
[ERROR] PowerMockito.when(service.start()).thenReturn(1)
When we use PowerMockito in scala, we face with overloading problem. Scala compiler will not be able to identify overloaded methods correctly and throws error saying ambiguous definition.
So if you want to use PowerMockito, mention your statement something as below, e.g.:
PowerMockito.when(SomeClass.staticmethod(someObject, someObject), Seq.empty[Object])
.thenReturn(expectedXml, Seq.empty[Object])
I'm trying to add functionality to the scala.collection.Iterable trait, more specifically, a printerate function that iterates through the elements and prints them out (to the console if there are no parameters, otherwise to the outputstream param). I'm using a predefined extension method that I created for object, printSelf(). However, this is causing an compiler error, 'Value printSelf is not a member of type parameter Object.' I'd also like to have this an a separate file so that it's easy for me to use between several projects and applications.
Here's my current code for my conversion file:
import java.io.OutputStream
import scala.collection.Iterable
package conversion{
class Convert {
implicit def object2SuperObject(o:Object) = new ConvertObject(o)
implicit def iterable2SuperIterable[Object](i:Iterable[Object]) = new ConvertIterable[Object](i)
}
class ConvertObject(o:Object){
def printSelf(){
println(o.toString())
}
def printSelf(os:OutputStream){
os.write(o.toString().getBytes())
}
}
class ConvertIterable[Object](i:Iterable[Object]){
def printerate(){
i.foreach {x => x.printSelf() }
}
def printerate(os:OutputStream){
i.foreach { x => x.printSelf(os) }
}
}
}
I'm also getting a similar error in the code that's trying to test this out, 'value printerate is not a member of scala.collection.immutable.Range':
import conversion.Convert
package test {
object program extends App {
new testObj(10) test
}
class testObj(i: Integer) {
def test(){
val range = 0.until(i)
0.until(i).printerate()
}
}
}
What's wrong with the way that I'm approaching this type conversion?
Several things in fact:
Convert should be an object, not a class.
You use Object instead of Any
You use Object as a generic type identifier, instead of the much less confusing T.
You do not import the implicit definitions (it's not enough to import the object itself).
This should work:
package conversion {
object Convert {
implicit def object2SuperObject(o: Any) = new ConvertObject(o)
implicit def iterable2SuperIterable[T](i:Iterable[T]) = new ConvertIterable[T](i)
}
class ConvertObject(o: Any){
def printSelf(){
println(o.toString())
}
def printSelf(os:OutputStream){
os.write(o.toString().getBytes())
}
}
class ConvertIterable[T](i:Iterable[T]){
import Convert.object2SuperObject
def printerate(){
i.foreach {x => x.printSelf() }
}
def printerate(os:OutputStream){
i.foreach { x => x.printSelf(os) }
}
}
}
import conversion.Convert._
Second file:
package test {
object program extends App {
new testObj(10) test
}
class testObj(i: Integer) {
def test(){
val range = 0.until(i)
0.until(i).printerate()
}
}
}
I have some (Akka) actor code that is using a case class + the copy constructor to update state:
def foo(state:StateCaseClass) : Receive = {
import state._
{
case Bar(updates) =>
context become foo(copy(/* change a limited number of things */))
// ... other message processing w/ lots of context become foo(copy(...))
}
}
I'd like to add below the import
def update = context become foo(copy(_))
so that the code can be
def foo(state:StateCaseClass) : Receive = {
import state._
def update = context become foo(copy(_))
{
case Bar(updates) =>
update(/* change a limited number of things */)
// ... etc
}
}
but that doesn't compile. I can of course tweak the def update a bit to get rid of most of boilerplate, but the copy still sticks around:
def foo(state:StateCaseClass) : Receive = {
import state._
def update(newState:StateCaseClass) = context become foo(newState)
{
case Bar(updates) =>
update(copy(/* change a limited number of things */))
// ... etc
}
}
Is there comparable syntax that will let me pass through the args to the case class copy constructor and dry out that last bit?
Disclaimer: I guess the best solution is to use context become explicitly. And I don't recommend you to use the code below.
I guess it's impossible without metaprogramming (macros). You have to create a method with default values for named parameters.
You could always create such method manually like this:
def update(filed1: Int = state.field1, field2: String = state.field2) =
context become foo(StateCaseClass(filed1, filed2))
...
update(field1 = 0)
...
update(field2 = "str")
But I guess it's not what you want.
The only way to get such method without metaprogramming is... to use method copy itself. Method copy calls constructor and you could call become in constructor.
The code below works, but I strongly don't recommend you to use it! It's a cryptocode and it will confuse all other developers.
import akka.actor._
trait ReceiveHelper extends PartialFunction[Any, Unit] {
def receive: PartialFunction[Any, Unit]
override def apply(v: Any) = receive(v)
override def isDefinedAt(v: Any) = receive isDefinedAt v
}
sealed trait TestActorMessage
case object Get extends TestActorMessage
case class SetInt(i: Int) extends TestActorMessage
case class SetString(s: String) extends TestActorMessage
class TestActor extends Actor {
case class Behaviour(intField: Int, strField: String) extends ReceiveHelper {
context become this
val receive: Receive = {
case Get => sender ! (intField -> strField)
case SetInt(i) => copy(intField = i)
case SetString(s) => copy(strField = s)
}
}
def receive = Behaviour(0, "init")
}
Usage:
val system = ActorSystem("testSystem")
val testActor = system.actorOf(Props[TestActor], "testActor")
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
implicit val timeout = Timeout(5 seconds)
testActor ? Get foreach println
// (0,init)
testActor ! SetInt(666)
testActor ? Get foreach println
// (666,init)
testActor ! SetString("next")
testActor ? Get foreach println
// (666,next)
I have an external process that I would like to treat as a
function from String=>String. Given a line of input, it will respond with a single line of output. It seems that I should use
scala.sys.process, which is clearly an elegant library that makes many
shell operations easily accessible from within scala. However, I
can't figure out how to perform this simple use case.
If I write a single line to the process' stdin, it prints the result
in a single line. How can I use sys.process to create a wrapper so I
can use the process interactively? For example, if I had an
implementation for ProcessWrapper, here is a program and it's output:
// abstract definition
class ProcessWrapper(executable: String) {
def apply(line: String): String
}
// program using an implementation
val process = new ProcessWrapper("cat -b")
println(process("foo"))
println(process("bar"))
println(process("baz"))
Output:
1 foo
2 bar
3 baz
It is important that the process is not reloaded for each call to process because there is a significant initialization step.
So - after my comment - this would be my solution
import java.io.BufferedReader
import java.io.File
import java.io.InputStream
import java.io.InputStreamReader
import scala.annotation.tailrec
class ProcessWrapper(cmdLine: String, lineListenerOut: String => Unit, lineListenerErr: String => Unit,
finishHandler: => Unit,
lineMode: Boolean = true, envp: Array[String] = null, dir: File = null) {
class StreamRunnable(val stream: InputStream, listener: String => Unit) extends Runnable {
def run() {
try {
val in = new BufferedReader(new InputStreamReader(this.stream));
#tailrec
def readLines {
val line = in.readLine
if (line != null) {
listener(line)
readLines
}
}
readLines
}
finally {
this.stream.close
finishHandler
}
}
}
val process = Runtime.getRuntime().exec(cmdLine, envp, dir);
val outThread = new Thread(new StreamRunnable(process.getInputStream, lineListenerOut), "StreamHandlerOut")
val errThread = new Thread(new StreamRunnable(process.getErrorStream, lineListenerErr), "StreamHandlerErr")
val sendToProcess = process.getOutputStream
outThread.start
errThread.start
def apply(txt: String) {
sendToProcess.write(txt.getBytes)
if (lineMode)
sendToProcess.write('\n')
sendToProcess.flush
}
}
object ProcessWrapper {
def main(args: Array[String]) {
val process = new ProcessWrapper("python -i", txt => println("py> " + txt),
err => System.err.println("py err> " + err), System.exit(0))
while (true) {
process(readLine)
}
}
}
The main part is the StreamRunnable, where the process is read in a thread and the received line is passed on to a "LineListener" (a simple String => Unit - function).
The main is just a sample implementation - calling python ;)
I'm not sure, but you want somethings like that ?
case class ProcessWrapper(executable: String) {
import java.io.ByteArrayOutputStream
import scala.concurrent.duration.Duration
import java.util.concurrent.TimeUnit
lazy val process = sys.runtime.exec(executable)
def apply(line: String, blockedRead: Boolean = true): String = {
process.getOutputStream().write(line.getBytes())
process.getOutputStream().flush()
val r = new ByteArrayOutputStream
if (blockedRead) {
r.write(process.getInputStream().read())
}
while (process.getInputStream().available() > 0) {
r.write(process.getInputStream().read())
}
r.toString()
}
def close() = process.destroy()
}
val process = ProcessWrapper("cat -b")
println(process("foo\n"))
println(process("bar\n"))
println(process("baz\n"))
println(process("buz\n"))
println(process("puz\n"))
process.close
Result :
1 foo
2 bar
3 baz
4 buz
5 puz
I think that PlayCLI is a better way.
http://blog.greweb.fr/2013/01/playcli-play-iteratees-unix-pipe/ came across this today and looks exactly like what you want
How about using an Akka actor. The actor can have state and thus a reference to an open program (in a thread). You can send messages to that actor.
ProcessWrapper might be a typed actor itself or just something that converts the calls of a function to a call of an actor. If you only have 'process' as method name, then wrapper ! "message" would be enough.
Having a program open and ready to receive commands sounds like an actor that receives messages.
Edit: Probably I got the requirements wrong. You want to send multiple lines to the same process. That's not possible with the below solution.
One possibility would be to add an extension method to the ProcessBuilder that allows for taking the input from a string:
implicit class ProcessBuilderWithStringInput(val builder: ProcessBuilder) extends AnyVal {
// TODO: could use an implicit for the character set
def #<<(s: String) = builder.#<(new ByteArrayInputStream(s.getBytes))
}
You can now use the method like this:
scala> ("bc":ProcessBuilder).#<<("3 + 4\n").!!
res9: String =
"7
"
Note that the type annotation is necessary, because we need two conversions (String -> ProcessBuilder -> ProcessBuilderWithStringInput, and Scala will only apply one conversion automatically.