Why does Clojure have the promise deliver function? - clojure

In Clojure, promise objects implement clojure.lang.IFn, and invoking the promise with a single argument fulfills the promise. That's how deliver is implemented:[source]
(defn deliver
"Delivers the supplied value to the promise, releasing any pending
derefs. A subsequent call to deliver on a promise will have no effect."
{:added "1.1"
:static true}
[promise val] (promise val))
If (deliver x y) is just a level of indirection over (x y), why use deliver at all?
I'm assuming this is supposed to help disambiguate promises from functions in some way—but the same argument could apply to using some promise-specific function to read from a promise rather than using the general deref function for that.

It's syntactic sugar to make code like this look nice:
(-> url
download
extract-value
(deliver consumer)
The deliver function used to have the behavior of ensuring that if you where the second caller to it an exception would be thrown. It was changed in 2011 and now the later calls are simply ignored.
Promises always had the same behavior if called as a function and if called from deliver, the function deliver only filled the roll of making something a little different look a little different. These days T would still use it to communicate with my future self

deref is a lot less general than the function-call mechanism. When you see something deref'd, you know it is fetching some value from somewhere. When you see (f x) you really have no idea what is happening if you don't already know what f is: it could do anything at all. deliver gives you more context.

Related

Immediately kill a running future thread

I'm using
(def f
(future
(while (not (Thread/interrupted))
(function-to-run))))
(Thread/sleep 100)
(future-cancel f)
to cancel my code after a specified amount of time (100ms).
The problem is, I need to cancel the already running function 'function-to-run' as well, it is important that it really stops executing that function after 100ms.
Can I somehow propagate the interrupted signal to the function?
The function is not third-party, I wrote it myself.
The basic thing to note here is: you cannot safely kill a thread without its own cooperation. Since you are the owner of the function you wish to be able to kill prematurely, it makes sense to allow the function to cooperate and die gracefully and safely.
(defn function-to-run
[]
(while work-not-done
(if-not (Thread/interrupted)
; ... do your work
(throw (InterruptedException. "Function interrupted...")))))
(def t (Thread. (fn []
(try
(while true
(function-to-run))
(catch InterruptedException e
(println (.getMessage e)))))))
To begin the thread
(.start t)
To interrupt it:
(.interrupt t)
Your approach was not sufficient for your use case because the while condition was checked only after control flow returned from function-to-run, but you wanted to stop function-to-run during its execution. The approach here is only different in that the condition is checked more frequently, namely, every time through the loop in function-to-run. Note that instead of throwing an exception from function-to-run, you could also return some value indicating an error, and as long as your loop in the main thread checks for this value, you don't have to involve exceptions at all.
If your function-to-run doesn't feature a loop where you can perform the interrupted check, then it likely is performing some blocking I/O. You may not be able to interrupt this, though many APIs will allow you to specify a timeout on the operation. In the worst case, you can still perform intermittent checks for interrupted in the function around your calls. But the bottom line still applies: you cannot safely forcibly stop execution of code running in the function; it should yield control cooperatively.
Note:
My original answer here involved presenting an example in which java's Thread.stop() was used (though strongly discouraged). Based on feedback in the comments, I revised the answer to the one above.

will an atom defined locally visible to other threads?

I have to following code for automation, the function accepts a unique number, and kick off a firefox. I could kick off multiple threads, each thread with a unique x passing to the function, so the function will be executed concurrently. Then will the local atom current-page be visible to other threads? if visible, then the reset! could set the atom an expected value from another thread
(defn consumer-scanning-pages [x]
(while true
(let [driver (get-firefox x)
current-page (atom 0)]
....
(reset! current-page ..)
)))
The atom will be visible to those threads you explicitly pass it to, to any further threads that those threads pass it to etc. It is no different in this respect to any other value that you may or may not pass around.
"Passing the atom to a thread" can be as simple as referring to an in-scope local it is stored in within the body of a Clojure thread-launching form:
(let [a (atom :foo)]
;; dereferencing the future object representing an off-thread computation
#(future
;; dereferencing the atom on another thread
#a))
;;= :foo
Merely creating an atom doesn't make it available to code that it is not explicitly made available to, and this is also true of code that happens to run on the thread that originally created the atom. (Consider a function that creates an atom, but never stores it in any externally visible data structures and ultimately returns an unrelated value. The atom it creates will become eligible for GC when the function returns at the latest; it will not be visible to any other code, on the same or any other thread.) Again, this is also the case with all other values.
It will not. You are creating a new atom each time that you call the function.
If you want a shared atom, just pass the atom as a param to consumer-scanning-pages

Deliver failure (Exception) to a promise

How can I make the deref of this promise throw an Exception, in the same way a future can cause an Exception if the body of the future throws one?
(let [p (promise)]
(something-that-could-deliver-an-error p)
#p) ; should explode with the delivered Exception
I'm currently considering doing this by delivering a fn to the promise, but I suspect there's a more idiomatic way to do this.
Background: I'm running multiple futures concurrently. If any of them error, I want to cancel all the other futures immediately and output the error. Maybe there's a better way?
Clojure's promises don't have a separate concept of "success" and "failure", rather, they only distinguish whether a promise has been realized. In other words, there's no way to get a Clojure core promise to throw a custom exception when you deference it.
If you're OK with going outside the standard library, you might try using deferred objects from Manifold instead:
http://aleph.io/manifold/deferreds.html
A deferred object can be fulfilled by either the success! or error! functions. The former behaves like deliver. The latter lets you fulfill the promise with an exception, which is thrown if the deferred is deref'd, but can also be "caught" by some of Manifold's other control-flow functions.
user=> (require '[manifold.deferred :as d])
nil
user=> (def my-deferred-value (d/deferred))
#'user/my-deferred-value
user=> (d/error! my-deferred-value (ex-info "Error!" {:failed true}))
true
user=> #my-deferred-value
ExceptionInfo Error! clojure.core/ex-info (core.clj:4617)

Queueing Method Calls So That They Are Performed By A Single Thread In Clojure

I'm building a wrapper around OrientDB in Clojure. One of the biggest limitations (IMHO) of OrientDB is that the ODatabaseDocumentTx is not thread-safe, and yet the lifetime of this thing from .open() to .close() is supposed to represent a single transaction, effectively forcing transactions to occur is a single thread. Indeed, thread-local refs to these hybrid database/transaction objects are provided by default. But what if I want to log in the same thread as I want to persist "real" state? If I hit an error, the log entries get rolled back too! That use case alone puts me off of virtually all DBMS's since most do not allow named transaction scope management. /soapbox
Anyways, OrientDB is the way it is, and it's not going to change for me. I'm using Clojure and I want an elegant way to construct a with-tx macro such that all imperative database calls within the with-tx body are serialized.
Obviously, I can brute-force it by creating a sentinel at the top level of the with-tx generated body and deconstructing every form to the lowest level and wrapping them in a synchronized block. That's terrible, and I'm not sure how that would interact with something like pmap.
I can search the macro body for calls to the ODatabaseDocumentTx object and wrap those in synchronized blocks.
I can create some sort of dispatching system with an agent, I guess.
Or I can subclass ODatabaseDocumentTx with synchronized method calls.
I'm scratching my head trying to come up with other approaches. Thoughts? In general the agent approach seems more appealing simply because if a block of code has database method calls interspersed, I would rather do all the computation up front, queue the calls, and just fire a whole bunch of stuff to the DB at the end. That assumes, however, that the computation doesn't need to ensure consistency of reads. IDK.
Sounds like a job for Lamina.
One option would be to use Executor with 1 thread in thread pool. Something like shown below. You can create a nice macro around this concept.
(import 'java.util.concurrent.Executors)
(import 'java.util.concurrent.Callable)
(defmacro sync [executor & body]
`(.get (.submit ~executor (proxy [Callable] []
(call []
(do ~#body))))))
(let [exe (Executors/newFixedThreadPool (int 1))
dbtx (sync exe (DatabaseTx.))]
(do
(sync exe (readfrom dbtx))
(sync exe (writeto dbtx))))
The sync macro make sure that the body expression is executed in the executor (which has only one thread) and it waits for the operation to complete so that all operations execute one by one.

How do Clojure futures and promises differ?

Both futures and promises block until they have calculated their values, so what is the difference between them?
Answering in Clojure terms, here are some examples from Sean Devlin's screencast:
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
Note that in the promise you are explicitly delivering a value that you select in a later computation (:fred in this case). The future, on the other hand, is being consumed in the same place that it was created. The some-expr is presumably launched behind the scenes and calculated in tandem (eventually), but if it remains unevaluated by the time it is accessed the thread blocks until it is available.
edited to add
To help further distinguish between a promise and a future, note the following:
promise
You create a promise. That promise object can now be passed to any thread.
You continue with calculations. These can be very complicated calculations involving side-effects, downloading data, user input, database access, other promises -- whatever you like. The code will look very much like your mainline code in any program.
When you're finished, you can deliver the results to that promise object.
Any item that tries to deref your promise before you're finished with your calculation will block until you're done. Once you're done and you've delivered the promise, the promise won't block any longer.
future
You create your future. Part of your future is an expression for calculation.
The future may or may not execute concurrently. It could be assigned a thread, possibly from a pool. It could just wait and do nothing. From your perspective you cannot tell.
At some point you (or another thread) derefs the future. If the calculation has already completed, you get the results of it. If it has not already completed, you block until it has. (Presumably if it hasn't started yet, derefing it means that it starts to execute, but this, too, is not guaranteed.)
While you could make the expression in the future as complicated as the code that follows the creation of a promise, it's doubtful that's desirable. This means that futures are really more suited to quick, background-able calculations while promises are really more suited to large, complicated execution paths. Too, promises seem, in terms of calculations available, a little more flexible and oriented toward the promise creator doing the work and another thread reaping the harvest. Futures are more oriented toward automatically starting a thread (without the ugly and error-prone overhead) and going on with other things until you -- the originating thread -- need the results.
Both Future and Promise are mechanisms to communicate result of asynchronous computation from Producer to Consumer(s).
In case of Future the computation is defined at the time of Future creation and async execution begins "ASAP". It also "knows" how to spawn an asynchronous computation.
In case of Promise the computation, its start time and [possible] asynchronous invocation are decoupled from the delivery mechanism. When computation result is available Producer must call deliver explicitly, which also means that Producer controls when result becomes available.
For Promises Clojure makes a design mistake by using the same object (result of promise call) to both produce (deliver) and consume (deref) the result of computation. These are two very distinct capabilities and should be treated as such.
There are already excellent answers so only adding the "how to use" summary:
Both
Creating promise or future returns a reference immediately. This reference blocks on #/deref until result of computation is provided by other thread.
Future
When creating future you provide a synchronous job to be done. It's executed in a thread from the dedicated unbounded pool.
Promise
You give no arguments when creating promise. The reference should be passed to other 'user' thread that will deliver the result.
In Clojure, promise, future, and delay are promise-like objects. They all represent a computation that clients can await by using deref (or #). Clients reuse the result, so that the computation is not run several times.
They differ in the way the computation is performed:
future will start the computation in a different worker thread. deref will block until the result is ready.
delay will perform the computation lazily, when the first client uses deref, or force.
promise offers most flexibility, as its result is delivered in any custom way by using deliver. You use it when neither future or delay match your use case.
I think chapter 9 of Clojure for the Brave has the best explanation of the difference between delay, future, and promise.
The idea which unifies these three concepts is this: task lifecycle. A task can be thought of as going through three stages: a task is defined, a task is executed, a task's result is used.
Some programming languages (like JavaScript) have similarly named constructs (like JS's Promise) which couple together several (or all) of the stages in the task lifecycle. In JS, for instance, it is impossible to construct a Promise object without providing it either with the function (task) which will compute its value, or resolveing it immediately with a constant value.
Clojure, however, eschews such coupling, and for this reason it has three separate constructs, each corresponding to a single stage in the task lifecycle.
delay: task definition
future: task execution
promise: task result
Each construct is concerned with its own stage of the task lifecycle and nothing else, thus disentangling higher order constructs like JS's Promise and separating them into their proper parts.
We see now that in JavaScript, a Promise is the combination of all three Clojure constructs listed above. Example:
const promise = new Promise((resolve) => resolve(6))
Let's break it down:
task definition: resolve(6) is the task.
task execution: there is an implied execution context here, namely that this task will be run on a future cycle of the event loop. You don't get a say in this; you can't, for instance, require that this task be resolved synchronously, because asynchronicity is baked into Promise itself. Notice how in constructing a Promise you've already scheduled your task to run (at some unspecified time). You can't say "let me pass this around to a different component of my system and let it decide when it wants to run this task".
task result: the result of the task is baked into the Promise object and can be obtained by thening or awaiting. There's no way to create an "empty" promised result to be filled out later by some yet unknown part of your system; you have to both define the task and simultaneously schedule it for execution.
PS: The separation which Clojure imposes allows these constructs to assume roles for which they would have been unsuited had they been tightly coupled. For instance, a Clojure promise, having been separated from task definition and execution, can now be used as a unit of transfer between threads.
Firstly, a Promise is a Future. I think you want to know the difference between a Promise and a FutureTask.
A Future represents a value that is not currently known but will be known in the future.
A FutureTask represents the result of a computation that will happen in future (maybe in some thread pool). When you try to access the result, if the computation has not happened yet, it blocks. Otherwise the result is returned immediately. There is no other party involved in the computing the result as the computation is specified by you in advance.
A Promise represents a result that will be delivered by the promiser to the promisee in future. In this case you are the promisee and the promiser is that one who gave you the Promise object. Similar to the FutureTask, if you try to access the result before the Promise has been fulfilled, it gets blocked till the promiser fulfills the Promise. Once the Promise is fulfilled, you get the same value always and immediately. Unlike a FutureTask, there is an another party involved here, one which made the Promise. That another party is responsible for doing the computation and fulfilling the Promise.
In that sense, a FutureTask is a Promise you made to yourself.