Completing scala promises race - scala

I can't seem to find anywhere whether complete and tryComplete are atomic operations on Promises in Scala. Promises are only supposed to be written to once, but if two tryCompletes happen concurrently in two different callbacks for example could something go wrong? Or are we assured that tryComplete is atomic?

First a quick note that success(...) is equivalent to calling complete(Success(...)) and tryComplete(...) is equivalent to complete(...).isCompleted.
In the docs it says
As mentioned before, promises have single-assignment semantics. As such, they can be completed only once. Calling success on a promise that has already been completed (or failed) will throw an IllegalStateException.
A promise can only complete once. Digging into the source code, DefaultPromise extends AtomicReference (ie. thread safe) and so all writes are atomic. This means that if you have two threads completing a promise, only one of them can ever succeed and it'll be whichever did so first. The other will throw an IllegalStateException.
Here's a small example of what happens when you try and complete a promise twice.
https://scastie.scala-lang.org/hTYBqVywSQCl8bFSgQI0Sg
Though apparently it seems one can circumvent the immutability of a Future by doing a bunch of weird casting acrobatics.
https://contributors.scala-lang.org/t/defaultpromise-violates-encapsulation/3440
One should probably avoid that.

Related

Scala Future `.onComplete` function discarded after call?

Are the function bodies passed to Future.onComplete(), and their closures, discarded and so garbage collected after they are called?
I ask because I'm writing an unbounded sequence of Future instances. Each Future has an .onComplete { case Failure(t)...} that refers to the previous known-good value from a previous Future. What I want to avoid is the total history of all Future results being kept in the JVM's memory because of references in closure bodies.
Perhaps Scala is more clever than this, but skimming the code related to execution contexts and futures isn't yielding much.
Thanks.
The class that normally implements Future and that you want to look at is DefaultPromise.
It contains mutable state that is being updated as the Future completes.
If you call onComplete and it has already been completed then it just schedules your callback immediately with the result. The callback is not recorded anywhere.
If you call onComplete while the result is not yet available, the callback is added to a list of "listeners".
When the result becomes available (someone calls complete on the promise), then all listeners are scheduled to run with that result, and the list of listeners is deleted (the internal state changes to "completed with this result")
This means that your callback chain is only being built up until the "upstream future" is incomplete. After that, everything gets resolved and garbage-collected.
"list of listeners" above is a bit of a simplification. There is special care being taken that these listeners do not end up referring to each-other, specifically to break reference loops that would prevent garbage collection to work when constructing futures recursively. Apparently this was indeed a problem in earlier versions.
The problem of leaks is solved by automatically breaking these chains of promises, so that promises don't refer to each other in a long chain. This
allows each promise to be individually collected. The idea is to "flatten"
the chain of promises, so that instead of each promise pointing to its
neighbour, they instead point directly the promise at the root of the
chain. This means that only the root promise is referenced, and all the
other promises are available for garbage collection as soon as they're no
longer referenced by user code.

Do NSOperationQueues always complete their queues before being deallocated?

I've been given the task to clean up some existing Swift code on our project which has just been converted to Swift 3. However, I keep seeing this which looks suspect to me.
OperationQueue().addOperation(someOperation)
Here are the concerns/issues I have...
The queue instance is created and used right there. No reference to it is stored for use elsewhere.
Because of the above, there will only ever be one operation in the queue, so why use the queue at all?
Since no one is holding a reference to the queue, under ARC, shouldn't it be instantly deallocated, and if so, what happens to the now-executing operation itself? Does it get interrupted, aborted or does it still complete?
Anyway, I'm wondering if I'm missing something or am unaware of a 'feature' of NSOperationQueue and NSOperations that make this code make sense. Can anyone shed light on this, or do you agree this is bad practice?
I've seen this pattern too. I think it works like NSURLConnection: the NSOperationQueue "knows" it has a pending operation and doesn't allow itself to go out of existence immediately. Also keep in mind that an NSOperationQueue isn't really a "thing"; it's a kind of front for an underlying dispatch queue.
It makes a certain sense to use this pattern in situations where there is no reasonable place to store a reference to the queue. And you can use it to powerful effect, as in this example where the operation has dependencies and thus is not executed until all the dependencies are.
Personally, however, if I'm not taking advantage of NSOperation features of that sort, I'd be more inclined to use GCD directly.
(As to your middle point, it would not make sense to execute on the main thread, because what if the operation is lengthy? You'd be blocking the main thread. However, do note that if all you're trying to say is "do this after everything else", Swift gives you defer.)

Clarification about Scala Future that never complete and its effect on other callbacks

While re-reading scala.lan.org's page detailing Future here, I have stumbled up on the following sentence:
In the event that some of the callbacks never complete (e.g. the callback contains an infinite loop), the other callbacks may not be executed at all. In these cases, a potentially blocking callback must use the blocking construct (see below).
Why may the other callbacks not be executed at all? I may install a number of callbacks for a given Future. The thread that completes the Future, may or may not execute the callbacks. But, because one callback is not playing footsie, the rest should not be penalized, I think.
One possibility I can think of is the way ExecutionContext is configured. If it is configured with one thread, then this may happen, but that is a specific behaviour and a not generally expected behaviour.
Am I missing something obvious here?
Callbacks are called within an ExecutionContext that has an eventually limited number of threads - if not by the specific context implementation, then by the underlying operating system and/or hardware itself.
Let's say your system's limit is OS_LIMIT threads. You create OS_LIMIT + 1 callbacks. From those, OS_LIMIT callbacks immediately get a thread each - and none ever terminate.
How can you guarantee that the remaining 1 callback ever gets a thread?
Sure, there could be some detection mechanisms built into the Scala library, but it's not possible in the general case to make an optimal implementation: maybe you want the callback to run for a month.
Instead (and this seems to be the approach in the Scala library), you could provide facilities for handling situations that you, the developer, know are risky. This removes the element of surprise from the system.
Perhaps most importantly - it enables the developer to "bake in" the necessary information about handler/task characteristics directly into his/her program, rather than relying on some obscure piece of language functionality (which may change from version to version).

RxJS is to events as promises are to async

In Requesting a clear, picturesque explanation of Reactive Extensions (RX)? I asked about what RX is all about, and I think, thanks to the provided answers I now got the idea.
In the referenced question i quoted a sentence from http://reactive-extensions.github.com/RxJS/ which says:
RxJS is to events as promises are to async.
Although I think that I got the idea behind RX, I do not get this sentence at all. I can not even say what it is exactly that I do not understand. It's more like ... I don't see the connection between the first and the second half of the sentence.
To me, this sentence sounds important and impressive, but I can hardly tell whether it's true or not, whether it's a great insight or not, and so on ...
Can anybody explain what the sentence means in words someone (like me) can understand who is new to all this reactive stuff?
Promises are a way to define computations that may happen once an asynchronous operation completes. RxJs is a way to define computations that may happen when one or more events, in a stream, occur (onNext), complete (onCompleted), or throw an exception (onError).

In Scala, does Futures.awaitAll terminate the thread on timeout?

So I'm writing a mini timeout library in scala, it looks very similar to the code here: How do I get hold of exceptions thrown in a Scala Future?
The function I execute is either going to complete successfully, or block forever, so I need to make sure that on a timeout the executing thread is cancelled.
Thus my question is: On a timeout, does awaitAll terminate the underlying actor, or just let it keep running forever?
One alternative that I'm considering is to use the java Future library to do this as there is an explicit cancel() method one can call.
[Disclaimer - I'm new to Scala actors myself]
As I read it, scala.actors.Futures.awaitAll waits until the list of futures are all resolved OR until the timeout. It will not Future.cancel, Thread.interrupt, or otherwise attempt to terminate a Future; you get to come back later and wait some more.
The Future.cancel may be suitable, however be aware that your code may need to participate in effecting the cancel operation - it doesn't necessarily come for free. Future.cancel cancels a task that is scheduled, but not yet started. It interrupts a running thread [setting a flag that can be checked]... which may or may not acknowledge the interrupt. Review Thread.interrupt and Thread.isInterrupted(). Your long-running task would normally check to see if it's being interrupted (your code), and self-terminate. Various methods (i.e. Thread.sleep, Object.wait and others) respond to the interrupt by throwing InterruptedException. You need to review & understand that mechanism to ensure your code will meet your needs within those constraints. See this.