- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Actor: super.receive(f) works, super.receive(idFun andThen f) causes scala.MatchError
Wed, 2010-06-09, 22:35
trait Logtor extends Actor ... {
val idFun : PartialFunction[Any, Any]= { case x => x}
abstract override def receive[R](f: PartialFunction[Any, R]): R = {
// super.receive(f) // <<< no error
super.receive(idFun andThen f) // <<< error!!!
//thesis.bsps.sort.WorkerNode@X: caught scala.MatchError:
//PivotedSlice(2,X)
}
The error is non-deterministic but reproducible.
Tests exist which always produced the error.
Switch Line 16 vs 17 to see.
http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/exp...
Testsuite is at:
Sbt_2.8/
src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala
It's Scala RC3. The project is build with SBT with managed libs only.
Any ideas what's wrong?
By the way, the app sorts distributed, with RegularSampling / PSRS.
Thanks in advance
stefan
Thu, 2010-06-10, 08:57
#2
Re: Actor: super.receive(f) works, super.receive(idFun andThen
On Thu, Jun 10, 2010 at 9:44 AM, Viktor Klang <viktor.klang@gmail.com> wrote:
Hello Stefan,
just to provide an alternative solution: AKKA - http://github.com/jboner/akka/blob/master/akka-core/src/main/scala/routing/Patterns.scala#L51
Sorry, too specific link, should be: http://github.com/jboner/akka/blob/master/akka-core/src/main/scala/routing/Patterns.scala
On Wed, Jun 9, 2010 at 11:35 PM, Stefan Kuhn <qn.666@gmx.net> wrote:trait Logtor extends Actor ... {
val idFun : PartialFunction[Any, Any]= { case x => x}
abstract override def receive[R](f: PartialFunction[Any, R]): R = {
// super.receive(f) // <<< no error
super.receive(idFun andThen f) // <<< error!!!
//thesis.bsps.sort.WorkerNode@X: caught scala.MatchError: //PivotedSlice(2,X)
}
The error is non-deterministic but reproducible.
Tests exist which always produced the error.
Switch Line 16 vs 17 to see.
http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/experimental/Logtor.scala
Testsuite is at:
Sbt_2.8/ src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala
It's Scala RC3. The project is build with SBT with managed libs only.
Any ideas what's wrong?
By the way, the app sorts distributed, with RegularSampling / PSRS.
Thanks in advance
stefan
Thu, 2010-06-10, 13:07
#3
Re: Actor: super.receive(f) works, super.receive(idFun andThen
Hi,
I haven't been able to reproduce it. A small self-contained example
would help.
Cheers,
Philipp
On 06/09/2010 11:35 PM, Stefan Kuhn wrote:
> trait Logtor extends Actor ... {
>
> val idFun : PartialFunction[Any, Any]= { case x => x}
>
> abstract override def receive[R](f: PartialFunction[Any, R]): R = {
> // super.receive(f) //<<< no error
> super.receive(idFun andThen f) //<<< error!!!
> //thesis.bsps.sort.WorkerNode@X: caught scala.MatchError:
> //PivotedSlice(2,X)
> }
>
> The error is non-deterministic but reproducible.
> Tests exist which always produced the error.
>
> Switch Line 16 vs 17 to see.
> http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/exp...
>
> Testsuite is at:
> Sbt_2.8/
> src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala
>
> It's Scala RC3. The project is build with SBT with managed libs only.
>
> Any ideas what's wrong?
> By the way, the app sorts distributed, with RegularSampling / PSRS.
>
>
> Thanks in advance
> stefan
>
>
>
> ----- stack trace -----
> thesis.bsps.sort.WorkerNode@250d593e: caught scala.MatchError:
> PivotedSlice(0,[I@6f649b44)
> scala.MatchError: PivotedSlice(0,[I@6f649b44)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$3.apply(RegularSamplingScalaActors.scala:126)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$3.apply(RegularSamplingScalaActors.scala:126)
> at scala.PartialFunction$$anon$2.apply(PartialFunction.scala:58)
> at scala.actors.Actor$class.receive(Actor.scala:487)
> at
> thesis.bsps.sort.WorkerNode.thesis$experimental$Logtor$$super$receive(RegularSamplingScalaActors.scala:95)
> at thesis.experimental.Logtor$class.receive(Logtor.scala:17)
> at thesis.bsps.sort.WorkerNode.receive(RegularSamplingScalaActors.scala:95)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply$mcV$sp(RegularSamplingScalaActors.scala:103)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply(RegularSamplingScalaActors.scala:103)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply(RegularSamplingScalaActors.scala:103)
> at scala.actors.Reactor$class.seq(Reactor.scala:280)
> at thesis.bsps.sort.WorkerNode.seq(RegularSamplingScalaActors.scala:95)
> at scala.actors.Reactor$$anon$3.andThen(Reactor.scala:258)
> at scala.actors.Combinators$class.loop(Combinators.scala:26)
> at thesis.bsps.sort.WorkerNode.loop(RegularSamplingScalaActors.scala:95)
> at scala.actors.Combinators$$anonfun$loop$1.apply(Combinators.scala:26)
> at scala.actors.Combinators$$anonfun$loop$1.apply(Combinators.scala:26)
> at
> scala.actors.Reactor$$anonfun$seq$1$$anonfun$apply$1.apply(Reactor.scala:277)
> at scala.actors.ReactorTask.run(ReactorTask.scala:34)
> at scala.actors.ReactorTask.compute(ReactorTask.scala:66)
> at scala.concurrent.forkjoin.RecursiveAction.exec(RecursiveAction.java:147)
> at
> scala.concurrent.forkjoin.ForkJoinTask.quietlyExec(ForkJoinTask.java:422)
> at
> scala.concurrent.forkjoin.ForkJoinWorkerThread.mainLoop(ForkJoinWorkerThread.java:340)
> at
> scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:325)
>
>
>
>
>
>
Thu, 2010-06-10, 15:27
#4
Re: Actor: super.receive(f) works, super.receive(idFun andThen f
I've stripped my example down to 130 LOCs. Is that good enough?
It's here
http://paste.pocoo.org/show/223927/
Or here ;)
-------------------------------
package thesis.bugs.scalaActors
import scala.actors.Actor, Actor._
trait LoggingActor extends Actor {
val shouldUseIdFun :Boolean
val idFun : PartialFunction[Any, Any]= { case x => x}
abstract override def receive[R](f: PartialFunction[Any, R]): R = {
if(shouldUseIdFun)
super.receive(idFun andThen f) //error
else
super.receive(f)
}
}
object IdFunProblem {
def main(args :Array[String]) {
println("Start without idFun")
var shouldUseIdFun = false
for(i <- 0 to 1000){
run(5,shouldUseIdFun)
}
println("Start WITH idFun")
shouldUseIdFun = true
for(i <- 0 to 1000){
run(5,shouldUseIdFun)
}
println("Done")
}
def run( p :Int, shouldUseIdFun :Boolean) {
val workers = (new Array[Actor](p)).zipWithIndex.map(x => new
WorkerNode(shouldUseIdFun, x._2))
workers.map(_.start)
val controller = new Controller(workers)
controller.start
val futResponse = controller !! StartController()
val result = futResponse()
}
}
sealed trait RegularSamplingMsg
case class StartController() extends RegularSamplingMsg
case class InitSlice[T <: Actor](coWorkers :Array[T], controller :Actor)
extends RegularSamplingMsg
case class Samples(fromID :Int) extends RegularSamplingMsg
case class Pivots(controller :Actor) extends RegularSamplingMsg
case class PivotedSlice(fromID :Int) extends RegularSamplingMsg
case class Result(fromID :Int) extends RegularSamplingMsg
import scala.actors.OutputChannel
class Controller[T <: Actor](workers :Array[T]) extends Actor {
sealed trait State
case object Init extends State
case class WaitingForSamples(var remaining :Int, sender
:OutputChannel[Any]) extends State
case class WaitingForResults(var remaining :Int, sender
:OutputChannel[Any]) extends State
var state :State = Init
val p = workers.size
def act = { loop { receive {
case StartController() => {
for(i <- 0 until p){
workers(i) ! InitSlice( workers, self)
}
state = WaitingForSamples(p, sender)
}
case Samples(from) => {
val sampleState = state.asInstanceOf[WaitingForSamples]
sampleState.remaining -= 1
if(sampleState.remaining == 0){
workers.map(_ ! Pivots( self))
state = new WaitingForResults(p,sampleState.sender )
}
}
case Result(from) => {
val resultState = state.asInstanceOf[WaitingForResults]
resultState.remaining -= 1
if(resultState.remaining == 0){
resultState.sender ! Array(1)
exit
}
}
}}}
}
class WorkerNode(val shouldUseIdFun :Boolean, id :Int) extends Actor
with LoggingActor {
type M = PartialFunction[Any,Unit]
sealed trait State
case object Init extends State
case class WaitingForPivots(coWorkers :Array[Actor],controller
:Actor) extends State
case class WaitingForPivotedSlices(var remaining :Int, controller
:Actor) extends State
var state :State = Init
def act = { loop { receive {
state match { //more elegant with direct state switch?
case Init =>
initFun
case _:WaitingForPivots =>
pivotFun
case _:WaitingForPivotedSlices =>
pivotSliceFun
case x =>
throw new IllegalStateException(id+") in state("+state+")
received: "+x)
}
}}}
val initFun :M = {
case InitSlice( coWorkers, controller) => {
val p = coWorkers.size
controller ! Samples(id)
state = WaitingForPivots( coWorkers, controller)
}
}
val pivotFun :M = {
case Pivots(controller) => {
val gotSliceState = state.asInstanceOf[WaitingForPivots]
val coWorkers = gotSliceState.coWorkers
val p = coWorkers.size
for(i <- 0 until p){
coWorkers(i) ! PivotedSlice(id)
}
state = WaitingForPivotedSlices(p, controller)
}
}
val pivotSliceFun :M = {
case PivotedSlice( slice) => {
val waitingState = state.asInstanceOf[WaitingForPivotedSlices]
waitingState.remaining -= 1
if(waitingState.remaining == 0){
waitingState.controller ! Result(id)
exit
}
}
}
}
Mon, 2010-06-14, 13:57
#5
Re: Actor: super.receive(f) works, super.receive(idFun andThen f
I've cut it further down
http://paste.pocoo.org/show/225263/
-stefan
----
package thesis.bugs.scalaActors
import scala.actors.Actor, Actor._, State._
trait LoggingActor extends Actor {
val shouldUseIdFun :Boolean
val idFun : PartialFunction[Any, Any]= { case x => x}
abstract override def receive[R](f: PartialFunction[Any, R]): R = {
if(shouldUseIdFun)
super.receive(idFun andThen f) //error
else
super.receive(f)
}
}
object IdFunProblem {
def main(args :Array[String]) {
println("Start without idFun")
var shouldUseIdFun = false
run(5,shouldUseIdFun)
println("Start WITH idFun")
shouldUseIdFun = true
for(i <- 0 to 5){
print("\n"+i+") ")
run(5,shouldUseIdFun)
}
println("Done")
}
def run( p :Int, shouldUseIdFun :Boolean) {
val workers = (new Array[Actor](p)).zipWithIndex.map(x => new
WorkerNode(shouldUseIdFun, x._2))
workers.map(_.start)
val controller = new Controller(workers)
controller.start
while (controller.getState != Terminated)
Thread.`yield`
}
}
sealed trait RegularSamplingMsg
case class Task[T <: Actor](coWorkers :Array[T], controller :Actor)
extends RegularSamplingMsg
case object TaskResult extends RegularSamplingMsg
case class Result(fromID :Int) extends RegularSamplingMsg
import scala.actors.OutputChannel
/**
* Controller sends N Workers a Tasks.
* Each Worker sends each Worker TaskResults.
* After a worker received N TaskResults it sends Result to the Controller
*
*/
class Controller[T <: Actor](workers :Array[T]) extends Actor {
val p = workers.size
def act = {
for(i <- 0 until p){
workers(i) ! Task( workers, self)
}
var waitingForNResults = p
loop { receive {
case Result(from) => {
waitingForNResults -= 1
if(waitingForNResults == 0){
exit
}
}
}}}
}
class WorkerNode(val shouldUseIdFun :Boolean, id :Int) extends Actor
with LoggingActor {
type M = PartialFunction[Any,Unit]
sealed trait State
case object WaitingForTask extends State
case class WaitingForTaskResults(var remaining :Int, controller
:Actor) extends State
var state :State = WaitingForTask
def act = { loop { receive {
state match { //more elegant with direct state switch?
case WaitingForTask =>
initFun
case _:WaitingForTaskResults =>
collectTaskResults
case x =>
throw new IllegalStateException(id+") in state("+state+")")
}
}}}
val initFun :M = {
case Task( coWorkers, controller) => {
val p = coWorkers.size
for(i <- 0 until p){
coWorkers(i) ! TaskResult
}
state = WaitingForTaskResults(p, controller)
}
}
val collectTaskResults :M = {
case TaskResult => {
val waitingState = state.asInstanceOf[WaitingForTaskResults]
waitingState.remaining -= 1
if(waitingState.remaining == 0){
waitingState.controller ! Result(id)
exit
}
}
}
}
Am 10.06.10 14:04, schrieb Philipp Haller:
> Hi,
>
> I haven't been able to reproduce it. A small self-contained example
> would help.
>
> Cheers,
> Philipp
>
>
> On 06/09/2010 11:35 PM, Stefan Kuhn wrote:
>> trait Logtor extends Actor ... {
>>
>> val idFun : PartialFunction[Any, Any]= { case x => x}
>>
>> abstract override def receive[R](f: PartialFunction[Any, R]): R = {
>> // super.receive(f) //<<< no error
>> super.receive(idFun andThen f) //<<< error!!!
>> //thesis.bsps.sort.WorkerNode@X: caught scala.MatchError:
>> //PivotedSlice(2,X)
>> }
>>
>> The error is non-deterministic but reproducible.
>> Tests exist which always produced the error.
>>
>> Switch Line 16 vs 17 to see.
>> http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/exp...
>>
>>
>> Testsuite is at:
>> Sbt_2.8/
>> src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala
>>
>> It's Scala RC3. The project is build with SBT with managed libs only.
>>
>> Any ideas what's wrong?
>> By the way, the app sorts distributed, with RegularSampling / PSRS.
>>
>>
>> Thanks in advance
>> stefan
>>
>>
>>
>> ----- stack trace -----
>> thesis.bsps.sort.WorkerNode@250d593e: caught scala.MatchError:
>> PivotedSlice(0,[I@6f649b44)
>> scala.MatchError: PivotedSlice(0,[I@6f649b44)
>> at
>> thesis.bsps.sort.WorkerNode$$anonfun$3.apply(RegularSamplingScalaActors.scala:126)
>>
>> at
>> thesis.bsps.sort.WorkerNode$$anonfun$3.apply(RegularSamplingScalaActors.scala:126)
>>
>> at scala.PartialFunction$$anon$2.apply(PartialFunction.scala:58)
>> at scala.actors.Actor$class.receive(Actor.scala:487)
>> at
>> thesis.bsps.sort.WorkerNode.thesis$experimental$Logtor$$super$receive(RegularSamplingScalaActors.scala:95)
>>
>> at thesis.experimental.Logtor$class.receive(Logtor.scala:17)
>> at
>> thesis.bsps.sort.WorkerNode.receive(RegularSamplingScalaActors.scala:95)
>> at
>> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply$mcV$sp(RegularSamplingScalaActors.scala:103)
>>
>> at
>> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply(RegularSamplingScalaActors.scala:103)
>>
>> at
>> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply(RegularSamplingScalaActors.scala:103)
>>
>> at scala.actors.Reactor$class.seq(Reactor.scala:280)
>> at thesis.bsps.sort.WorkerNode.seq(RegularSamplingScalaActors.scala:95)
>> at scala.actors.Reactor$$anon$3.andThen(Reactor.scala:258)
>> at scala.actors.Combinators$class.loop(Combinators.scala:26)
>> at thesis.bsps.sort.WorkerNode.loop(RegularSamplingScalaActors.scala:95)
>> at scala.actors.Combinators$$anonfun$loop$1.apply(Combinators.scala:26)
>> at scala.actors.Combinators$$anonfun$loop$1.apply(Combinators.scala:26)
>> at
>> scala.actors.Reactor$$anonfun$seq$1$$anonfun$apply$1.apply(Reactor.scala:277)
>>
>> at scala.actors.ReactorTask.run(ReactorTask.scala:34)
>> at scala.actors.ReactorTask.compute(ReactorTask.scala:66)
>> at
>> scala.concurrent.forkjoin.RecursiveAction.exec(RecursiveAction.java:147)
>> at
>> scala.concurrent.forkjoin.ForkJoinTask.quietlyExec(ForkJoinTask.java:422)
>> at
>> scala.concurrent.forkjoin.ForkJoinWorkerThread.mainLoop(ForkJoinWorkerThread.java:340)
>>
>> at
>> scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:325)
>>
>>
>>
>>
>>
>>
>>
>
>
Mon, 2010-06-14, 16:27
#6
Re: Actor: super.receive(f) works, super.receive(idFun andThen f
To make it more comprehensive, I've added the error at the very end of
the sources:
http://paste.pocoo.org/show/225312/
Why does super.receive(idFun andThen f) instead of super.receive(f)
changes the behaviour?
Mon, 2010-06-14, 16:47
#7
Re: Actor: super.receive(f) works, super.receive(idFun andThen
Since no one else tackled this:
You're using Partial Functions improperly. That being, if you want to combine PartialFunctions, andThen will compose them. However, it assumes that each one *completely* matches the space, or throws an error.
If you want to join them "case-wise" so-to-speak you want to use the orElse function. When combining receive methods from an actor hierarchy, orElse is how you need to do it, unless you want the first function to be the only thing that has a chance to match against the input.
- Josh
P.S. - Not sure what variant of Scala you're using, but the code you posted is quite... uncompilable for me.
On Wed, Jun 9, 2010 at 5:35 PM, Stefan Kuhn <qn.666@gmx.net> wrote:
You're using Partial Functions improperly. That being, if you want to combine PartialFunctions, andThen will compose them. However, it assumes that each one *completely* matches the space, or throws an error.
If you want to join them "case-wise" so-to-speak you want to use the orElse function. When combining receive methods from an actor hierarchy, orElse is how you need to do it, unless you want the first function to be the only thing that has a chance to match against the input.
- Josh
P.S. - Not sure what variant of Scala you're using, but the code you posted is quite... uncompilable for me.
On Wed, Jun 9, 2010 at 5:35 PM, Stefan Kuhn <qn.666@gmx.net> wrote:
trait Logtor extends Actor ... {
val idFun : PartialFunction[Any, Any]= { case x => x}
abstract override def receive[R](f: PartialFunction[Any, R]): R = {
// super.receive(f) // <<< no error
super.receive(idFun andThen f) // <<< error!!!
//thesis.bsps.sort.WorkerNode@X: caught scala.MatchError: //PivotedSlice(2,X)
}
The error is non-deterministic but reproducible.
Tests exist which always produced the error.
Switch Line 16 vs 17 to see.
http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/experimental/Logtor.scala
Testsuite is at:
Sbt_2.8/ src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala
It's Scala RC3. The project is build with SBT with managed libs only.
Any ideas what's wrong?
By the way, the app sorts distributed, with RegularSampling / PSRS.
Thanks in advance
stefan
Mon, 2010-06-14, 16:57
#8
Re: Actor: super.receive(f) works, super.receive(idFun andThen
On Mon, Jun 14, 2010 at 5:43 PM, Josh Suereth <joshua.suereth@gmail.com> wrote:
Since no one else tackled this:
Erm, I sent a link to an implementation of a logging actor :p
Also, in the link was sample code to do PartialFunction filter and intercept
You're using Partial Functions improperly. That being, if you want to combine PartialFunctions, andThen will compose them. However, it assumes that each one *completely* matches the space, or throws an error.
If you want to join them "case-wise" so-to-speak you want to use the orElse function. When combining receive methods from an actor hierarchy, orElse is how you need to do it, unless you want the first function to be the only thing that has a chance to match against the input.
- Josh
P.S. - Not sure what variant of Scala you're using, but the code you posted is quite... uncompilable for me.
On Wed, Jun 9, 2010 at 5:35 PM, Stefan Kuhn <qn.666@gmx.net> wrote:
trait Logtor extends Actor ... {
val idFun : PartialFunction[Any, Any]= { case x => x}
abstract override def receive[R](f: PartialFunction[Any, R]): R = {
// super.receive(f) // <<< no error
super.receive(idFun andThen f) // <<< error!!!
//thesis.bsps.sort.WorkerNode@X: caught scala.MatchError: //PivotedSlice(2,X)
}
The error is non-deterministic but reproducible.
Tests exist which always produced the error.
Switch Line 16 vs 17 to see.
http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/experimental/Logtor.scala
Testsuite is at:
Sbt_2.8/ src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala
It's Scala RC3. The project is build with SBT with managed libs only.
Any ideas what's wrong?
By the way, the app sorts distributed, with RegularSampling / PSRS.
Thanks in advance
stefan
Mon, 2010-06-14, 17:07
#9
Re: Actor: super.receive(f) works, super.receive(idFun andThen
My bad! no harm meant.
On Mon, Jun 14, 2010 at 11:51 AM, Viktor Klang <viktor.klang@gmail.com> wrote:
On Mon, Jun 14, 2010 at 11:51 AM, Viktor Klang <viktor.klang@gmail.com> wrote:
On Mon, Jun 14, 2010 at 5:43 PM, Josh Suereth <joshua.suereth@gmail.com> wrote:
Since no one else tackled this:
Erm, I sent a link to an implementation of a logging actor :p
Also, in the link was sample code to do PartialFunction filter and intercept
You're using Partial Functions improperly. That being, if you want to combine PartialFunctions, andThen will compose them. However, it assumes that each one *completely* matches the space, or throws an error.
If you want to join them "case-wise" so-to-speak you want to use the orElse function. When combining receive methods from an actor hierarchy, orElse is how you need to do it, unless you want the first function to be the only thing that has a chance to match against the input.
- Josh
P.S. - Not sure what variant of Scala you're using, but the code you posted is quite... uncompilable for me.
On Wed, Jun 9, 2010 at 5:35 PM, Stefan Kuhn <qn.666@gmx.net> wrote:
trait Logtor extends Actor ... {
val idFun : PartialFunction[Any, Any]= { case x => x}
abstract override def receive[R](f: PartialFunction[Any, R]): R = {
// super.receive(f) // <<< no error
super.receive(idFun andThen f) // <<< error!!!
//thesis.bsps.sort.WorkerNode@X: caught scala.MatchError: //PivotedSlice(2,X)
}
The error is non-deterministic but reproducible.
Tests exist which always produced the error.
Switch Line 16 vs 17 to see.
http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/experimental/Logtor.scala
Testsuite is at:
Sbt_2.8/ src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala
It's Scala RC3. The project is build with SBT with managed libs only.
Any ideas what's wrong?
By the way, the app sorts distributed, with RegularSampling / PSRS.
Thanks in advance
stefan
Mon, 2010-06-14, 17:17
#10
Re: Actor: super.receive(f) works, super.receive(idFun andThen
Also, as I stated in #scala, the issue is more that isDefinedAt in the andThen function is essentially *exactly* the same as the first function's andThen. You'll have to manually override this.
- Josh
On Mon, Jun 14, 2010 at 11:43 AM, Josh Suereth <joshua.suereth@gmail.com> wrote:
- Josh
On Mon, Jun 14, 2010 at 11:43 AM, Josh Suereth <joshua.suereth@gmail.com> wrote:
Since no one else tackled this:
You're using Partial Functions improperly. That being, if you want to combine PartialFunctions, andThen will compose them. However, it assumes that each one *completely* matches the space, or throws an error.
If you want to join them "case-wise" so-to-speak you want to use the orElse function. When combining receive methods from an actor hierarchy, orElse is how you need to do it, unless you want the first function to be the only thing that has a chance to match against the input.
- Josh
P.S. - Not sure what variant of Scala you're using, but the code you posted is quite... uncompilable for me.
On Wed, Jun 9, 2010 at 5:35 PM, Stefan Kuhn <qn.666@gmx.net> wrote:
trait Logtor extends Actor ... {
val idFun : PartialFunction[Any, Any]= { case x => x}
abstract override def receive[R](f: PartialFunction[Any, R]): R = {
// super.receive(f) // <<< no error
super.receive(idFun andThen f) // <<< error!!!
//thesis.bsps.sort.WorkerNode@X: caught scala.MatchError: //PivotedSlice(2,X)
}
The error is non-deterministic but reproducible.
Tests exist which always produced the error.
Switch Line 16 vs 17 to see.
http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/experimental/Logtor.scala
Testsuite is at:
Sbt_2.8/ src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala
It's Scala RC3. The project is build with SBT with managed libs only.
Any ideas what's wrong?
By the way, the app sorts distributed, with RegularSampling / PSRS.
Thanks in advance
stefan
Mon, 2010-06-14, 17:27
#11
Re: Actor: super.receive(f) works, super.receive(idFun andThen
Thanks, problem solved.
For the record:
My problem was the idDefinedAt result of idFun andThen f. It is first
suprising, because if idFun andThen f results in f(idFun(x)) I expected
that isDefinedAt of the resulting function tests if idFun isDefinedAt x
&& f isDefinedAt idFun(x). Because of possible sideeffects in idFun, it
does make sense.
Still suprising.
trait LoggingActor extends Actor {
val shouldUseIdFun :Boolean
abstract override def receive[R](f: PartialFunction[Any, R]): R = {
if(shouldUseIdFun)
super.receive(idFun2(f))
else
super.receive(f)
}
def idFun2[R](f: PartialFunction[Any, R]): PartialFunction[Any, R] = {
new PartialFunction[Any, R] {
def isDefinedAt(x: Any): Boolean = f.isDefinedAt(x)
def apply(x: Any): R = {
f(x)
}
}
}
}
Am 14.06.10 17:43, schrieb Josh Suereth:
> Since no one else tackled this:
>
> You're using Partial Functions improperly. That being, if you want to
> combine PartialFunctions, andThen will compose them. However, it
> assumes that each one *completely* matches the space, or throws an error.
>
> If you want to join them "case-wise" so-to-speak you want to use the
> orElse function. When combining receive methods from an actor
> hierarchy, orElse is how you need to do it, unless you want the first
> function to be the only thing that has a chance to match against the input.
>
> - Josh
>
> P.S. - Not sure what variant of Scala you're using, but the code you
> posted is quite... uncompilable for me.
>
> On Wed, Jun 9, 2010 at 5:35 PM, Stefan Kuhn > wrote:
>
> trait Logtor extends Actor ... {
>
> val idFun : PartialFunction[Any, Any]= { case x => x}
>
> abstract override def receive[R](f: PartialFunction[Any, R]): R = {
> // super.receive(f) // <<< no error
> super.receive(idFun andThen f) // <<< error!!!
> //thesis.bsps.sort.WorkerNode@X: caught scala.MatchError:
> //PivotedSlice(2,X)
> }
>
> The error is non-deterministic but reproducible.
> Tests exist which always produced the error.
>
> Switch Line 16 vs 17 to see.
> http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/exp...
>
> Testsuite is at:
> Sbt_2.8/
> src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala
>
> It's Scala RC3. The project is build with SBT with managed libs only.
>
> Any ideas what's wrong?
> By the way, the app sorts distributed, with RegularSampling / PSRS.
>
>
> Thanks in advance
> stefan
>
>
>
> ----- stack trace -----
> thesis.bsps.sort.WorkerNode@250d593e: caught scala.MatchError:
> PivotedSlice(0,[I@6f649b44)
> scala.MatchError: PivotedSlice(0,[I@6f649b44)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$3.apply(RegularSamplingScalaActors.scala:126)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$3.apply(RegularSamplingScalaActors.scala:126)
> at scala.PartialFunction$$anon$2.apply(PartialFunction.scala:58)
> at scala.actors.Actor$class.receive(Actor.scala:487)
> at
> thesis.bsps.sort.WorkerNode.thesis$experimental$Logtor$$super$receive(RegularSamplingScalaActors.scala:95)
> at thesis.experimental.Logtor$class.receive(Logtor.scala:17)
> at
> thesis.bsps.sort.WorkerNode.receive(RegularSamplingScalaActors.scala:95)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply$mcV$sp(RegularSamplingScalaActors.scala:103)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply(RegularSamplingScalaActors.scala:103)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply(RegularSamplingScalaActors.scala:103)
> at scala.actors.Reactor$class.seq(Reactor.scala:280)
> at
> thesis.bsps.sort.WorkerNode.seq(RegularSamplingScalaActors.scala:95)
> at scala.actors.Reactor$$anon$3.andThen(Reactor.scala:258)
> at scala.actors.Combinators$class.loop(Combinators.scala:26)
> at
> thesis.bsps.sort.WorkerNode.loop(RegularSamplingScalaActors.scala:95)
> at
> scala.actors.Combinators$$anonfun$loop$1.apply(Combinators.scala:26)
> at
> scala.actors.Combinators$$anonfun$loop$1.apply(Combinators.scala:26)
> at
> scala.actors.Reactor$$anonfun$seq$1$$anonfun$apply$1.apply(Reactor.scala:277)
> at scala.actors.ReactorTask.run(ReactorTask.scala:34)
> at scala.actors.ReactorTask.compute(ReactorTask.scala:66)
> at
> scala.concurrent.forkjoin.RecursiveAction.exec(RecursiveAction.java:147)
> at
> scala.concurrent.forkjoin.ForkJoinTask.quietlyExec(ForkJoinTask.java:422)
> at
> scala.concurrent.forkjoin.ForkJoinWorkerThread.mainLoop(ForkJoinWorkerThread.java:340)
> at
> scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:325)
>
>
>
>
>
>
>
just to provide an alternative solution: AKKA - http://github.com/jboner/akka/blob/master/akka-core/src/main/scala/routing/Patterns.scala#L51
On Wed, Jun 9, 2010 at 11:35 PM, Stefan Kuhn <qn.666@gmx.net> wrote: