|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--org.erights.e.elib.ref.Ref
Safe: Objects that handle E eventual-send message delivery requests themselves. Represents a resolvable reference hopefully eventually designating some object.
Because Refs are seen by E only through the Ref protocol, any public methods that subclasses want to make visible should be static methods that take a 'self' instance as an argument, rather than instance methods.
A Ref is often a facet of a promise. A promise is a composite consisting of a Ref as arrow tail, and often a resolver of some sort as arrow head. Usually, the resolver will be of type Resolver, but not necessarily.
Field Summary | |
static String |
BROKEN
Enabled: |
static String |
EVENTUAL
Enabled: |
static String |
NEAR
Enabled: |
private static StaticMaker |
OptRefMaker
Initialized lazily to avoid a circular initialization problem |
(package private) static UnconnectedRef |
TheViciousRef
The canonical reference BROKEN by TheViciousMarker. |
Constructor Summary | |
Ref()
Enabled: |
Method Summary | |
static Ref |
broken(Throwable problem)
Enabled: Return a Ref broken allegedly because of problem. |
abstract Object |
callAll(String verb,
Object[] args)
Suppressed: Use E.callAll(obj, verb, args) rather than obj.callAll(verb, args). |
(package private) abstract void |
commit()
Used by a resolvers to turn off switchability, and thereby make this Ref equivalent to its current target. |
static Ref |
disconnected(Throwable problem,
Object prevRef)
Enabled: Return a Disconnected reference -- a broken reference with the same identity as some far reference. |
TypeDesc |
getAllegedType()
Suppressed: |
ProxyHandler |
getOptProxyHandler(Class handlerClass)
Suppressed: If this is a handled Proxy whose handler is an instance of handlerClass, then return that handler; else null. |
static StaticMaker |
GetRefMaker()
Enabled: |
void |
ignore()
Suppressed: This default implemetation currently does nothing |
static boolean |
isBroken(Object ref)
Enabled: Is this reference known never to be able to deliver messages? |
static boolean |
isDeepFrozen(Object ref)
Enabled: XXX Currently just delegates to isDeepPassByCopy, which will make errors of omission (the safe kind). |
static boolean |
isDeepPassByCopy(Object ref)
Enabled: Would ref be successfully coerced by DeepPassByCopyAuditor? |
private static boolean |
isDeepPassByCopy(Object ref,
IdentityMap optSofar)
We move the work to the two argument form so it can break cycles. |
private static boolean |
isDeepPassByCopyClass(Class clazz)
Are instances of clazz necessarily DeepPassByCopy? |
static boolean |
isEventual(Object ref)
Enabled: Does this reference support eventual sends but not immediate calls? |
static boolean |
isFar(Object ref)
Enabled: Is 'ref' both eventual and resolved? |
static boolean |
isNear(Object ref)
Enabled: Does this reference designate an object in this vat? |
static boolean |
isPassByProxy(Object ref)
Enabled: Would ref be successfully coerced by PassByProxyGuard? |
static boolean |
isPBC(Object ref)
Enabled: Would ref be successfully coerced by PassByConstructionAuditor? |
static boolean |
isPersistent(Object ref)
Enabled: Can this reference be saved and restored with a SerializationStream and
an UnserializationStream as parameterized by a
PersistenceReplacer and
PersistenceReviver ?
|
abstract boolean |
isResolved()
Suppressed: |
static boolean |
isResolved(Object ref)
Enabled: A reference isResolved when it is known what object it designates. |
static boolean |
isSameEver(Object left,
Object right)
Enabled: If two object references are the same(), they are indistinguishable up to brokeness XXX no longer true, changed to designational equivalence, need to write up. |
static boolean |
isSelfish(Object ref)
Enabled: A NEAR reference that isn't Selfless is Selfish, and designates a Selfish object. |
static boolean |
isSelfless(Object ref)
Enabled: A Selfless object only has value-based sameness. |
static boolean |
isSettled(Object ref)
Enabled: A reference is settled when it has a fully determined identity. |
static Object[] |
makeBufferingPromise()
Deprecated. Currently unused, so we may decide to retire this. |
static Object[] |
makeSwitchablePromise(Object target)
Deprecated. Currently unused, so we may decide to retire this. |
static Object |
optBroken(Throwable optProblem)
Enabled: If optProblem is null, then return null; else Ref.broken(optProblem) |
abstract Throwable |
optProblem()
Suppressed: Use Ref.optProblem(obj) rather than obj.optProblem(). |
static Throwable |
optProblem(Object ref)
Enabled: If isBroken(ref), this returns the alleged reason why it's broken; otherwise null. |
SealedBox |
optSealedDispatch(Brand brand)
Suppressed: For now, returns null. |
static SealedBox |
optSealedDispatch(Object ref,
Brand brand)
Enabled: If the ref has anything to give to one who has the unsealer for the provided brand, ask it to return a SealedBox containing that payload. |
Script |
optShorten(String verb,
Object[] args)
Suppressed: Return null |
static Object[] |
promise()
Enabled: Returns the two facets of a local promise -- a SwitchableRef and a LocalResolver. |
Object |
resolution()
Suppressed: Use Ref.resolution/1
rather than obj.resolution(). |
static Object |
resolution(Object ref)
Enabled: User-means of Ref shortening. |
(package private) abstract Ref |
resolutionRef()
Used to implement resolution(), and for internal use in the promise package. |
boolean |
respondsTo(String verb,
int arity)
Suppressed: |
abstract Ref |
sendAll(String verb,
Object[] args)
Suppressed: Use E.sendAll(obj, verb, args) rather than obj.sendAll(verb, args). |
abstract Throwable |
sendAllOnly(String verb,
Object[] args)
Suppressed: Use E.sendAllOnly(obj, verb, args) rather than obj.sendAllOnly(verb, args). |
void |
sendMsg(Message msg)
Suppressed: Eventually sends a packaged message to this object. |
(package private) abstract void |
setTarget(Ref newTarget)
Used by a resolvers to change the target. |
String |
state()
Suppressed: Use Ref.state(obj) rather than obj.state(). |
static String |
state(Object ref)
Enabled: One of EVENTUAL , NEAR , or BROKEN . |
static Callable |
toCallable(Object target)
Enabled: Return an object that's E-equivanetlt to target, but has Java-type Callable. |
static Ref |
toRef(Object target)
Enabled: Return an object that's E-equivanetlt to target, but has Java-type Ref. |
String |
toString()
Suppressed: |
static Object |
whenBroken(Object ref,
OneArgFunc reactor)
Enabled: Should a breakable reference ever become broken, even if it became fulfilled in the meantime, then the reactor is invoked once with a broken reference. |
static Throwable |
whenBrokenOnly(Object ref,
OneArgFunc reactor)
Enabled: Like whenBroken(Object, OneArgFunc) but without a conventional
return result. |
static Object |
whenResolved(Object ref,
OneArgFunc reactor)
Enabled: Used for the when-catch construct. |
static Throwable |
whenResolvedOnly(Object ref,
OneArgFunc reactor)
Enabled: Like whenResolved(Object, OneArgFunc) but without a
conventional return result. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
private static StaticMaker OptRefMaker
public static final String NEAR
public static final String EVENTUAL
public static final String BROKEN
static final UnconnectedRef TheViciousRef
Constructor Detail |
public Ref()
Method Detail |
public static StaticMaker GetRefMaker()
public static Object[] promise()
The SwitchableRef starts on a BufferingRef, where the LocalResolver holds the buffer.
public static Object[] makeSwitchablePromise(Object target)
With a Switcher, the promise can be redirected repeatedly before being committed.
public static Object[] makeBufferingPromise()
To make and hold both facets of a buffering promise without the extra allocation, in E do:
def Message := <type:org.erights.e.elib.prim.Message> def resolver = FlexList.fromType(Message) def ref = BufferingRef(resolver)or, in Java, do:
import org.erights.e.elib.prim.Message; FlexList resolver = FlexList.fromType(Message.class); BufferingRef ref = new BufferingRef(resolver);
public static Ref broken(Throwable problem)
public static Object optBroken(Throwable optProblem)
public static Ref disconnected(Throwable problem, Object prevRef)
'prevRef' must currently be a far or disconnected reference. While it seems sensible to allow one to make a Disconnected reference to a Near object, there's no way to provide this in Ref without destroying our layering -- the independence of local ELib from the CapTP layer.
public static boolean isNear(Object ref)
isNear/1 must be thread safe, in order for
Ref.isDeepPassByCopy/2
to be thread safe.
state(Object)
public static boolean isEventual(Object ref)
state(Object)
public static boolean isBroken(Object ref)
isBroken/1 must be thread safe, in order for
BootRefHandler.packageArg/4
to be thread safe.
state(Object)
public static Throwable optProblem(Object ref)
public static String state(Object ref)
EVENTUAL
, NEAR
, or BROKEN
.
An EVENTUAL reference is unreliably invokable by E.send() -- ie, the message may or may not get delivered to the designated recipient). However, it will deliver messages reliably and in order until it fails. Should it fail, it will eventually become broken.
A NEAR reference is reliably invokable by E.send*() and E.call*() (and possibly directly by Java's "."). The object is synchronously callable and therefore within the same concurrency and atomic failure unit -- the same vat.
A BROKEN reference is one that fails to designate an object. It has an associated Throwable that explains what problem resulted in this condition.
A Ref may be in any of these three states. A non-Ref is equivalent to a NEAR Ref. An EVENTUAL Ref may become NEAR or BROKEN. A NEAR Ref must forever remain NEAR, and a BROKEN Ref must forever remain BROKEN.
state/1 must be thread safe, in order for
BootRefHandler.packageArg/4
to be thread safe.
public static Object resolution(Object ref)
If isEventual(ref) or isBroken(ref), this returns ref (or a Ref equivalent to ref but possibly more efficient).
If isNear(ref), this returns a non-Ref. The resolution of a NEAR reference may be called by both java dot and E.call*(), even if the original was only callable by E.call*(). Non-Refs return themselves.
First unwraps deflections.
resolution/1 must be thread safe, in order for
BootRefHandler.packageArg/4
to be thread safe.
public static Callable toCallable(Object target)
public static Ref toRef(Object target)
public static boolean isResolved(Object ref)
NEAR and BROKEN references are necessarily resolved. A reference that isn't resolved is a promise, which is necessarily EVENTUAL. A resolved EVENTUAL reference is a Far reference.
public static boolean isFar(Object ref)
public static boolean isSettled(Object ref)
If x and y are settled references, then the E language's 'x == y' (which expands to 'Ref same(x, y)' must yield either true or false. Whereas if either or both are unsettled, then 'x == y' may instead throw a NotSettledException since it cannot yet be determined whether further settling will cause the same question to yield true or false.
Only settled references may be used as keys in EMaps (hashtables), since only from a fully determined identity is there enough information to (internal to the E implementation) calculate a hash.
Settled references are a subset of Resolved references -- unresolved references (Promises) are necessarily unsettled. Objects with object-creation identity are "Selfish" (they have a "self"). Those without are "Selfless". For objects defined in the E language, only PassByCopy are Selfless, all others are Selfish (and implicitly PassByProxy). Near and Far references to Selfish objects are settled. Broken references are settled. When a Far reference breaks, the corresponding Broken reference retains the settled identity of its Far reference, since identity must be stable. Other Broken references are the same iff their problems are the same.
Far references cannot point at Selfless objects (although RemotePromises can, as a transient state). Therefore, the only case left is a Near reference to a Selfless object. A Near reference to a Selfless object is settled iff the Selfless object is settled. Just as two Selfless objects are the same iff they are of the same types are their parts are recursively the same, a Selfless object is settled when all its parts are recursively settled. For example,
[x, y]is settled iff x and y are both settled.
In the recursive defintions of both sameness and settledness, cycles are fine. For example,
def a := ["left", a, "right"]defines an infinite (cyclic) settled tree.
public static boolean isSelfless(Object ref)
Selfless objects are immutable, and compare for sameness based only on their type and state. As a result, an E implementation can transparently copy or merge copies of Selfless objects at will, with no effect visible from the E language. (XXX talk about rational tree comparison.)
isSelfless of a non-NEAR reference is false. This is a bit weird for FarRef, and DisconnectedRef, as they are listed (for implementation reasons) as Selfless objects (either actual or HONORARY).
org.erights.e.elib.tables.Selfless
public static boolean isSelfish(Object ref)
Selfish objects have creation-identity, ie, normal EQness. For Selfish objects, Java's "x==y" and E's "x==y" (ie, ELib's "E.same(x,y)") agree.
isSelfish of a non-NEAR reference is false. This is a bit wierd for FarRef and DisconnectedRef, as they both have the creation identity of the object they (originally) designate(d). However, for these, E's "x==y" does not agree with Java's "x==y".
public static boolean isPassByProxy(Object ref)
A PassByProxy object is passed between vats by creating a FarRef for it on the remote end that forwards back to the original. PassByProxy objects must be Selfish, and only exist in their hosting vat.
It's safe to provide this test, since PassByProxyGuard's coerce() either returns ref or fails. Ie, it doesn't actually coerce.
isPassByProxy of a non-NEAR reference is false.
isPassByProxy/1 must be thread safe, in order for
BootRefHandler.packageArg/4
to be thread safe.
public static boolean isPBC(Object ref)
PassByConstruction objects are passed between vats by constructing a new object in the destination vat to serve as its representative. We often speak of the original and each of its representatives individually as presences, and the conceptual object that they all jointly represent as an Unum. The most common and most trivial case of PassByConstruction is PassByCopy, in which case each presence is a Selfess, transparent, immutable copy of each other.
It's mostly safe to provide this test, since PassByConstructionAuditor's coerce() either returns ref or fails. Ie, it mostly doesn't coerce. The exception is that coerce() will coerce an Array to a ConstList, which should be transparent to the E language programmer.
isPBC on a non-NEAR reference is false, which is a bit wierd for UnconnectedRef and DisconnectedRef, as (for implementation reasons) they are listed as PassByConstruction.
public static boolean isDeepPassByCopy(Object ref)
It's mostly safe to provide this test, since DeepPassByCopyAuditor's coerce() either returns ref or fails. Ie, it mostly doesn't coerce. The exception is that coerce() will coerce an array to a ConstList, which should be transparent to the E language programmer.
isDeepPassByCopy on a non-NEAR reference is false, which is a bit wierd for UnconnectedRef and DisconnectedRef.
Of all PassByCopy data types where an instance might be considered DeepPassByCopy based on a dynamic check of its contents, we currently only perform such a dynamic check for arrays and ConstLists. XXX should we instead check ConstMaps and ConstSets as well? Or perhaps all PassByCopy objects, since they are all transparent, so there should be a reliable generic way to enumerate all their contents?
isDeepPassByCopy/1 must be thread safe, in order for
BootRefHandler.packageArg/4
to be thread safe.
public static boolean isDeepFrozen(Object ref)
private static boolean isDeepPassByCopyClass(Class clazz)
isDeepPassByCopyClass/1 must be thread safe, in order for
Ref.isDeepPassByCopy/2
to be thread safe.
private static boolean isDeepPassByCopy(Object ref, IdentityMap optSofar)
isDeepPassByCopy/2 must be thread safe, in order for
Ref.isDeepPassByCopy/1
to be thread safe: Note that optSoFar will always start as null, and
therefore will only ever hold a thread-specific map, and so need not
itself be thread safe.
public static boolean isPersistent(Object ref)
SerializationStream
and
an UnserializationStream
as parameterized by a
PersistenceReplacer
and
PersistenceReviver
?
The cases are
org.erights.e.elib.serial.Persistent
(including StemCell
s) are persistent.
org.erights.e.elib.serial.Persistent#HONORARY
classes are
persistent.
public static boolean isSameEver(Object left, Object right)
The E language's "x == y" expands to "Ref.isSameEver(x, y)".
If (x == y && Ref optProblem(x) == Ref optProblem(y)) then substituting one for the other must be semantically transparent XXX no longer true, changed to designational equivalence, need to write up. See "When Are Two Things the Same?".
Sameness is stable, but it is only total among settled references. If 'x == y' yield true or false then the same comparison must forever afterwards yield the same answer. However, if either or both are unsettled, it may throw NotSettledException instead. Throws a NotSettledException if left and right are not yet settled enough to determine whether they will designate the same settled identity.
public static Object whenResolved(Object ref, OneArgFunc reactor)
If ref never becomes resolved, the reactor is not invoked. Should ref become resolved, the reactor will be invoked exactly once. For example, if ref becomes fulfilled and then broken, the reactor will hear of exactly one of these events.
Once ref becomes resolved the reactor will be invoked with the resolution. Should the reactor be invoked with a non-broken value (and therefore a fulfilled value), all earlier messages sent on ref before the whenResolved are guaranteed to have been successfully delivered.
whenBroken(Object, OneArgFunc)
public static Throwable whenResolvedOnly(Object ref, OneArgFunc reactor)
whenResolved(Object, OneArgFunc)
but without a
conventional return result.
public static Object whenBroken(Object ref, OneArgFunc reactor)
A vat-crossing reference that gets garbage collected before a partition is not broken by that partition, and therefore doesn't need to inform the reactor. Once a reference is logically garbage (unreachable), it may or may not have been collected yet, and so may or may not inform the reactor of partitions that happen after it is garbage.
whenResolved(Object, OneArgFunc)
public static Throwable whenBrokenOnly(Object ref, OneArgFunc reactor)
whenBroken(Object, OneArgFunc)
but without a conventional
return result.
public static SealedBox optSealedDispatch(Object ref, Brand brand)
That SealedBox should, of course, be sealed by the sealer for that brand, but that's up to the ref. If ref has nothing to give to one who has the unsealer for this brand, return null.
public String toString()
toString
in class Object
public abstract Throwable optProblem()
When we're BROKEN, our subclass must return a non-null problem. When we're not BROKEN, our subclass must return null.
All implementations of optProblem/0 must be thread safe, in
order for Ref.state/0
to be thread safe.
optProblem(Object)
abstract Ref resolutionRef()
All implementations of resolutionRef/0 must be thread safe, in
order for Ref.resolution/0
to be thread
safe.
public Object resolution()
Ref.resolution/1
rather than obj.resolution().
Our subclass must either provide 'this', or an object which is equivalent but less indirect. If the resolution() is 'this', then our state() must be BROKEN or EVENTUAL. However, subclasses will typically only override resolutionRef(). The only difference between the two is on a NearRef.
All implementations of resolution/0 must be thread safe, in
order for Ref.resolution/1
to be thread
safe.
public String state()
All implementations of state/0 must be thread safe, in order
for Ref.isNear/1
to be thread safe: The
default implementation here is inductively thread safe even though it
doesn't synchronize, in that it's made only from thread safe parts used
together in a monotonic fashion.
state(Object)
public Script optShorten(String verb, Object[] args)
optShorten
in interface Callable
public abstract Object callAll(String verb, Object[] args)
callAll
in interface Callable
public void sendMsg(Message msg)
To the client, this has the same semantics as sendAll(java.lang.String, java.lang.Object[])
or
sendAllOnly(java.lang.String, java.lang.Object[])
, and the default implementation here in Ref just
delegates to these. However, those subclasses that can reuse
the Message should do so as a nice optimization, and to preserve the
SendingContext
info
captured in msg for causality tracing and debugging.
XXX SECURITY ALERT, No longer true:
This is package scope, since only trusted code is assumed to not
resuse a Resolver so as to break distributed transparency. (This
safeguard isn't crucial, and isn't even a big deal, but is nice.)
public abstract Ref sendAll(String verb, Object[] args)
public abstract Throwable sendAllOnly(String verb, Object[] args)
public abstract boolean isResolved()
public SealedBox optSealedDispatch(Brand brand)
optSealedDispatch
in interface Amplifiable
public ProxyHandler getOptProxyHandler(Class handlerClass)
This is for internal use only. As with other instance methods of Ref it is effectively suppressed for taming by virtue of Ref being a kind of Callable.
All implementations of getOptProxyHandler/1 must be thread
safe, in order for
BootRefHandler.getOptBootRefHandler/1
to be thread safe: The default implementation here merely returns null.
public TypeDesc getAllegedType()
getAllegedType
in interface Callable
public boolean respondsTo(String verb, int arity)
respondsTo
in interface Callable
public void ignore()
abstract void setTarget(Ref newTarget)
abstract void commit()
If the current target is already equivalent to this Ref, then this Ref
becomes broken by a ViciousCycleException
.
|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |