Walnut/Distributed Computing/Testing for Equality in a Distributed System

From Erights

Revision as of 17:16, 20 April 2011 by Ansible (Talk | contribs)
Jump to: navigation, search

pplQLr With the bases loaded you struck us out with that asnewr!

Making your own Promises

If you write a function or method that must get values from a far object before returning an answer, your function should return a promise for the answer, and fulfill that answer later. You can create your own promises using Ref.promise() in E:

 # E sample
 def calcMilesBeforeEmptyVow(carRcvr) {
     def [milesBeforeEmptyPromise, milesBeforeEmptyResolver] := Ref.promise()
     def fuelRemainingVow := carRcvr <- getFuelRemaining()
     def mpgVow := carRcvr <- getEfficiency()
     when (fuelRemainingVow, mpgVow) -> {
         milesBeforeEmptyResolver.resolve(mpgVow * fuelRemainingVow)
     } catch prob {
         milesBeforeEmptyResolver.smash(`Car Lost: $prob`)
     return milesBeforeEmptyPromise
 #....Meanwhile, somewhere else in the program....
 def myCar {
     to getFuelRemaining() {return 5}
     to getEfficiency() {return 2}
 def milesVow := calcMilesBeforeEmptyVow(myCar)
 when (milesVow) -> {
     println(`miles before empty = $milesVow`)
 } catch e {println(`Error: $e`)}

This example highlights several different features of promises. The basic idea of the example is that the function calcMilesBeforeEmptyVow(carRcvr) will eventually compute the number of miles the car can still travel before it is out of fuel; later in the program, when this computation is resolved, the program will print the value. However, before we can do the computation, we must first get both the fuelRemaining and the milesPerGallon values from the remote car.

The promise and the resolver for that promise are created as a pair using Ref.promise(). They are "normal" variables in the sense that they can be passed as arguments, returned from methods as answers, and sent eventual messages. Resolvers truly are ordinary objects. There are 3 restrictions on the promises: they cannot accept immediate calls, they cannot be tested for equality, and they cannot be used as keys in hash tables.

In this example, the function returns the milesBeforeEmptyPromise to the caller just as it would return any other kind of value. To cause the promise to resolve, the function calls the resolver (or sends to the resolver if the resolver may be remote to your program) with the "resolve(value)" method. To break the promise (which produces a problem that will cause the catch clause of a when-catch to execute), call the resolver with the "smash(problem)" method.

It is possible to chain resolutions: you can resolve a promise by handing the resolver another promise (though if you hand the resolver the promise which it is intended to resolve, E will detect the problem and automatically break the promise--a promise resolved to itself can never be fulfilled). If you resolve a promise with another promise, the original promise is not yet considered resolved, i.e., the when-catch body will not be activated by such a resolution. The when-catch body will only be activated when the entire promise chain is resolved, and there is an actual reference to an actual object available.

Personal tools
more tools