How to create a groovy actor which keeps execution unless stopped

115 Views Asked by At

I wanna create an Actor which keeps executing a task, then it can be stopped by an external call to stop, but got quite blocked.

The actor should look the following

myActor = actor {
        loop {
            react { message ->
                if(message instanceof String && "stop".equals(message))
                {
                    stop()
                } 
            }
        }

        while(true)
        {
                // do some work
        }
    }

After the creation, the actor can be started via in my test file, @BeforeMethod:

myActor.start()

And its handle can be kept by the main thread and stopped via below command in my test file, @AfterMethod:

myActor.send "stop"

However, I cannot get above approach working. First of all, I find I do not need to "myActor.start()", after the @BeforeMethod, it just runs automatically;

Secondly, although I tried to call "myActor.send "stop" in my test file's @AfterMethod, it looks like the loop{} of myActor is never visited and keeps working with the while{}.

I tried also to put the loop{} into while{}, but it is still not working and loop{} is still not called

Did I miss anything?

Thanks!

1

There are 1 best solutions below

0
On

This code snippet should show you how to structure your code:

def myActor = Actors.actor {
    loop {
        react { message ->
            if(message instanceof String && "stop".equals(message))
            {
                stop()
            }
        }
    }
}

myActor.metaClass.afterStop = {
    while(true)
    {
        // do some work
        println "After finished"
        return
    }
}

myActor.send "stop"

sleep 5000

A few notes:

  1. Placing the while after loop() in the same body indeed has the effect of the control flow reaching the while loop before the loop may even start.
  2. You may well consider calling stop() on the actor directly instead of sending an artificial "stop" message. The afterStop handler will be still invoked.
  3. Actors started through the actor() factory method are started automatically.