How to cancel Future in Scala? - multithreading

Java Future has cancel method, which can interrupt the thread, which runs the Future task. For example, if I wrap an interruptible blocking call in a Java Future I can interrupt it later.
Scala Future provides no cancel method. Suppose I wrap an interruptible blocking call in a Scala Future. How can I interrupt it?

This is not yet a part of the Futures API, but may be added as an extension in the future.
As a workaround, you could use the firstCompletedOf to wrap 2 futures - the future you want to cancel and a future that comes from a custom Promise. You could then cancel the thus created future by failing the promise:
def cancellable[T](f: Future[T])(customCode: => Unit): (() => Unit, Future[T]) = {
val p = Promise[T]
val first = Future firstCompletedOf Seq(p.future, f)
val cancellation: () => Unit = {
() =>
first onFailure { case e => customCode}
p failure new Exception
}
(cancellation, first)
}
Now you can call this on any future to obtain a "cancellable wrapper". Example use-case:
val f = callReturningAFuture()
val (cancel, f1) = cancellable(f) {
cancelTheCallReturningAFuture()
}
// somewhere else in code
if (condition) cancel() else println(Await.result(f1))
EDIT:
For a detailed discussion on cancellation, see Chapter 4 in the Learning concurrent programming in Scala book.

I haven't tested this, but this expands on the answer of Pablo Francisco PĂ©rez Hidalgo. Instead of blocking waiting for the java Future, we use an intermediate Promise instead.
import java.util.concurrent.{Callable, FutureTask}
import scala.concurrent.{ExecutionContext, Promise}
import scala.util.Try
class Cancellable[T](executionContext: ExecutionContext, todo: => T) {
private val promise = Promise[T]()
def future = promise.future
private val jf: FutureTask[T] = new FutureTask[T](
new Callable[T] {
override def call(): T = todo
}
) {
override def done() = promise.complete(Try(get()))
}
def cancel(): Unit = jf.cancel(true)
executionContext.execute(jf)
}
object Cancellable {
def apply[T](todo: => T)(implicit executionContext: ExecutionContext): Cancellable[T] =
new Cancellable[T](executionContext, todo)
}

By cancelling I guess you would like to violently interrupt the future.
Found this segment of code: https://gist.github.com/viktorklang/5409467
Did a few tests and seems to work fine!
Enjoy :)

I think it is possible to reduce the complexity of the implementations provided by making use of the Java 7 Future interface and its implementations.
Cancellable can build a Java future which is the one to be cancelled by its cancel method. Another future can wait for its completion thus becoming the observable interface which is itself immutable in state:
class Cancellable[T](executionContext: ExecutionContext, todo: => T) {
private val jf: FutureTask[T] = new FutureTask[T](
new Callable[T] {
override def call(): T = todo
}
)
executionContext.execute(jf)
implicit val _: ExecutionContext = executionContext
val future: Future[T] = Future {
jf.get
}
def cancel(): Unit = jf.cancel(true)
}
object Cancellable {
def apply[T](todo: => T)(implicit executionContext: ExecutionContext): Cancellable[T] =
new Cancellable[T](executionContext, todo)
}

Related

Kotlin Coroutines : Waiting for multiple threads to finish

So looking at Coroutines for the first time, I want to process a load of data in parallel and wait for it to finish. I been looking around and seen RunBlocking and Await etc but not sure how to use it.
I so far have
val jobs = mutableListOf<Job>()
jobs += GlobalScope.launch { processPages(urls, collection) }
jobs += GlobalScope.launch { processPages(urls, collection2) }
jobs += GlobalScope.launch { processPages(urls, collection3) }
I then want to know/wait for these to finish
You don't need to manually keep track of your cuncurrent jobs if you use the concept of structured concurrency. Assuming that your processPages function performs some kind of blocking IO, you can encapsulate your code into the following suspending function, which executes your code in an IO dispatcher designed for this kind of work:
suspend fun processAllPages() = withContext(Dispatchers.IO) {
// withContext waits for all children coroutines
launch { processPages(urls, collection) }
launch { processPages(urls, collection2) }
launch { processPages(urls, collection3) }
}
Now, from if a topmost function of your application is not already a suspending function, then you can use runBlocking to call processAllPages:
runBlocking {
processAllPages()
}
You can use async builder function to process a load of data in parallel:
class Presenter {
private var job: Job = Job()
private var scope = CoroutineScope(Dispatchers.Main + job) // creating the scope to run the coroutine. It consists of Dispatchers.Main (coroutine will run in the Main context) and job to handle the cancellation of the coroutine.
fun runInParallel() {
scope.launch { // launch a coroutine
// runs in parallel
val deferredList = listOf(
scope.asyncIO { processPages(urls, collection) },
scope.asyncIO { processPages(urls, collection2) },
scope.asyncIO { processPages(urls, collection3) }
)
deferredList.awaitAll() // wait for all data to be processed without blocking the UI thread
// do some stuff after data has been processed, for example update UI
}
}
private fun processPages(...) {...}
fun cancel() {
job.cancel() // invoke it to cancel the job when you don't need it to execute. For example when UI changed and you don't need to process data
}
}
Extension function asyncIO:
fun <T> CoroutineScope.asyncIO(ioFun: () -> T) = async(Dispatchers.IO) { ioFun() } // CoroutineDispatcher - runs and schedules coroutines
GlobalScope.launch is not recommended to use unless you want the coroutine to be operating on the whole application lifetime and not cancelled prematurely.
Edit: as mentioned by Roman Elizarov you can try not to use awaitAll() function unless you want to update UI or do something else right away after all data are processed.
Following approach can be used.
fun myTask() {
GlobalScope.launch {
val task = listOf(
async {
},
async {
}
)
task.awaitAll()
}
}

Stop Thread in Kotlin

First of all, I'm new in Kotlin, so please be nice :).
It's also my first time posting on StackOverflow
I want to literally STOP the current thread that I created but nothing works.
I tried quit(), quitSafely(), interrupt() but nothing works.
I created a class (Data.kt), in which I create and initialize a Handler and HandlerThread as follows :
class Dispatch(private val label: String = "main") {
var handler: Handler? = null
var handlerThread: HandlerThread? = null
init {
if (label == "main") {
handlerThread = null
handler = Handler(Looper.getMainLooper())
} else {
handlerThread = HandlerThread(label)
handlerThread!!.start()
handler = Handler(handlerThread!!.looper)
}
}
fun async(runnable: Runnable) = handler!!.post(runnable)
fun async(block: () -> (Unit)) = handler!!.post(block)
fun asyncAfter(milliseconds: Long, function: () -> (Unit)) {
handler!!.postDelayed(function, milliseconds)
}
fun asyncAfter(milliseconds: Long, runnable: Runnable) {
handler!!.postDelayed(runnable, milliseconds)
}
companion object {
val main = Dispatch()
private val global = Dispatch("global")
//fun global() = global
}
}
And now, in my DataManager, I use these to do asynchronous things :
fun getSomething(forceNetwork: Boolean ) {
val queue1 = Dispatch("thread1") // Create a thread called "thread1"
queue1.async {
for (i in 0..2_000_000) {
print("Hello World")
// Do everything i want in the current thread
}
// And on the main thread I call my callback
Dispatch.main.async {
//callback?.invoke(.........)
}
}
}
Now, in my MainActivity, I made 2 buttons :
One for running the function getSomething()
The other one is used for switching to another Controller View :
val button = findViewById<Button>(R.id.button)
button.setOnClickListener {
DataManager.getSomething(true)
}
val button2 = findViewById<Button>(R.id.button2)
button2.setOnClickListener {
val intent = Intent(this, Test::class.java) // Switch to my Test Controller
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
startActivity(intent)
finish()
}
Is there a way to stop the thread, because when I switch to my second View, print("Hello World") is still triggered, unfortunately.
Thanks for helping me guys I hope that you understand !
A thread needs to periodically check a (global) flag and when it becomes true then the thread will break out from the loop. Java threads cannot be safely stopped without its consent.
Refer to page 252 here http://www.rjspm.com/PDF/JavaTheCompleteReference.pdf that describes the true story behind the legend.
I think that a truly interruptible thread is only possible through the support of the operating system kernel. The actual true lock is held deep down by the CPU hardware microprocessor.

Scala future and its callback works in the same execution context

I call def activateReward by Akka actors and execution OracleClient.rewardActivate(user) sometimes is very slow (the database is outside of my responsibility and belongs to another company).
When database is slow the thread pool is exhausted and can not effectively allocate more threads to run callbacks future.onComplete because callbacks and futures works in the same execution context.
Please advise how to execute code in the callback asynchronously from threads which allocated for futures OracleClient.rewardActivate(user)
class RewardActivatorHelper {
private implicit val ec = new ExecutionContext {
val threadPool = Executors.newFixedThreadPool(1000)
def execute(runnable: Runnable) {threadPool.submit(runnable)}
def reportFailure(t: Throwable) {throw t}
}
case class FutureResult(spStart:Long, spFinish:Long)
def activateReward(msg:Msg, time:Long):Unit = {
msg.users.foreach {
user =>
val future:Future[FutureResult] = Future {
val (spStart, spFinish) = OracleClient.rewardActivate(user)
FutureResult(spStart, spFinish)
}
future.onComplete {
case Success(futureResult:FutureResult) =>
futureResult match {
case res:FutureResult => Logger.writeToLog(Logger.LogLevel.DEBUG,s"started:${res.spStart}finished:${res.spFinish}")
case _ => Logger.writeToLog(Logger.LogLevel.DEBUG, "some error")
}
case Failure(e:Throwable) => Logger.writeToLog(Logger.LogLevel.DEBUG, e.getMessage)
}
}
}
}
You can specify the execution context explicitly instead of implicitly for the onComplete callback by doing something along these lines:
import java.util.concurrent.Executors
import scala.concurrent.duration.Duration
object Example extends App {
import scala.concurrent._
private implicit val ec = new ExecutionContext {
val threadPool = Executors.newFixedThreadPool(1000)
def execute(runnable: Runnable) {threadPool.submit(runnable)}
def reportFailure(t: Throwable) {throw t}
}
val f = Future {
println("from future")
}
f.onComplete { _ =>
println("I'm done.")
}(scala.concurrent.ExecutionContext.Implicits.global)
Await.result(f, Duration.Inf)
}
This will of course not solve the underlying problem of a database not keeping up, but might be good to know anyway.
To clarify: I let the onComplete callback be handled by the standard global execution context. You might want to create a separate one.

Make an actor sleep

I want to make an actor sleep for a while, specifically it should decide whether to sleep itself depending on a condition:
class MyActor extends Actor {
def receive {
case "doWork" => doWork()
}
def doWork(): Unit = {
// doing some work
val condition = calculateCondition
if (condition) {
// sleep for 5 seconds
// Thread.sleep(5000)
}
}
}
I'm pretty much sure it's not a good thing to call Thread.sleep(5000) inside an actor and there should be another way. Therefore, how do I make it sleep?
I would look to do this using changes of state/behaviour for the Actor. Akka gives you a couple of means of doing this: you can implement a full-on state machine, or make use of context.become (and mix in akka.actor.Stash), and have the actor pass (scheduled) messages to itself. The former feels like overkill for this case, so here is how I would look to code it up:
import akka.actor._
import scala.concurrent.duration._
class MySleepyActor(duration: FiniteDuration = (5 seconds)) extends Actor with Stash {
import context._
override def preStart() { become(running) }
def receive = PartialFunction.empty
def running: Actor.Receive = {
case "doWork" =>
if (doWork()) {
scheduleReactivate
become(paused)
}
case "wakeUp" => // already awake
}
def paused: Actor.Receive = {
case "doWork" => stash()
case "wakeUp" =>
unstashAll()
become(running)
}
def scheduleReactivate: Unit = {
system.scheduler.scheduleOnce(duration, self, "wakeUp")
}
def doWork(): Boolean = {
// doing some work, then:
calculateCondition
}
}
Note: I have not tested this code! Should give you some ideas to work with, though.

Groovy concurrency: A better way to aggregate results semantically?

I need to call a number of methods in parallel and wait for results. Each relies on different resources, so they may return at different times. I need to wait until I receive all results or time out after a certain amount of time.
I could just spawn threads with a reference to a shared object via a method call, but is there a better, more groovy way to do this?
Current Implementation:
Executors exec = Executors.newFixedThreadPool(10);
for (obj in objects) {
def method = {
def result = new ResultObject(a: obj, b: obj.callSomeMethod())
result
} as Callable<ResultObject>
callables << method
}
List<Future<ResultObject>> results = exec.invokeAll(callables)
for (result in results) {
try{
def searchResult = result.get()
println 'result retrieved'
} catch (Exception e)
{
println 'exception'
e.printStackTrace()
}
}
}
A Groovier solution is to use GPars - a concurrency library written in Groovy.
import static groovyx.gpars.GParsExecutorsPool.withPool
withPool {
def callable = {obj -> new ResultObject(a: obj, b: obj.callSomeMethod())}.async()
List<ResultObject> results = objects.collect(callable)*.get()
}
AbstractExecutorService.invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
The groovy part would be using closures as Callable

Resources