public final class BasicObjectEndpoint extends Object implements ObjectEndpoint, TrustEquivalence, Serializable
Endpoint
for
sending requests to the object and a Uuid
to identify
the object at that Endpoint
.
In addition to the Endpoint
and the
Uuid
, BasicObjectEndpoint
instances also
contain a flag indicating whether or not the instance participates
in distributed garbage collection (DGC).
The newCall
method can be used to send a
request to the remote object that this object references.
BasicObjectEndpoint
class acts as the DGC
client for all of its instances that participate in DGC (which
are called live remote references). That is, it tracks the
existence and reachability of live remote references and makes
dirty calls and clean calls to the associated
server-side DGC implementations, as described below.
The server-side behavior of dirty and clean calls is specified
by BasicJeriExporter
. When the DGC client makes a dirty or
clean call to a given Endpoint
, the behavior is
effectively that of using a BasicObjectEndpoint
containing that Endpoint
and the object identifier
d32cd1bc-273c-11b2-8841-080020c9e4a1
(and that doesn't
itself participate in DGC), wrapped in a BasicInvocationHandler
with no client or server
constraints, wrapped in an instance of a dynamic proxy class that
implements an interface with the following remote methods:
long dirty(Uuid clientID, long sequenceNum, Uuid[] ids)
throws RemoteException
;
void clean(Uuid clientID, long sequenceNum, Uuid[] ids, boolean strong)
throws RemoteException;
clientID
is the DGC client's universally unique
identifier, which is generated using UuidFactory.generate
. sequenceNum
identifies the
sequence number of the dirty or clean call with respect to all
other dirty and clean calls made by the same DGC client (regardless
of the Endpoint
that the calls are made to). All
dirty and clean calls made by a DGC client must have a unique
sequence number that monotonically increases with the temporal
order of the states (of reachable live remote references) that the
calls assert. A dirty call asserts that live remote references
with the called Endpoint
and each of the object
identifiers in ids
exist for the identified DGC
client. A clean call asserts that there are no (longer) live
remote references with the called Endpoint
and each of
the object identifiers in ids
for the identified DGC
client.
The tracked live remote references are categorized by their
Endpoint
and further categorized by their object
identifier (with the Endpoint
and object identifier
pair identifying a remote object). When a new live remote
reference is created, either by construction or deserialization, it
is remembered among the live remote references with the same
Endpoint
and object identifier, and its reachability
is tracked with a phantom reference. If there is not already a
live remote reference with the same Endpoint
and
object identifier, the DGC client makes a dirty call to the
server-side DGC implementation at that Endpoint
, with
that object identifier in the ids
argument. Dirty
calls for multiple newly created live remote references with the
same Endpoint
may be batched as one dirty call (such
as for multiple live remote references deserialized from the same
stream).
Each successful dirty call establishes or renews a lease for the
DGC client with the server-side DGC implementation at the
Endpoint
that the dirty call was made to. The
duration of the lease granted by the server is conveyed as the
return value of the dirty call, in milliseconds starting from some
time during the processing of the dirty call. While there are live
remote references with a given Endpoint
, the DGC
client attempts to maintain a valid lease with that
Endpoint
by renewing its lease with successive dirty
calls. The DGC client should take into consideration network and
processing latencies of the previous dirty call and the next
required dirty call in choosing when to renew a lease. If the DGC
client has reason to assume that its lease with a given
Endpoint
might have expired, then in subsequent dirty
calls to that Endpoint
, it should include the object
identifiers of all currently reachable live remote references with
that Endpoint
. If a dirty call returns a negative
lease duration or throws a NoSuchObjectException
, the DGC
client should refrain from making further dirty calls to the same
Endpoint
until a new live remote reference with that
Endpoint
is created.
If a dirty call fails with a communication exception other than
a NoSuchObjectException
, the DGC client implementation
should make a reasonable effort to retry the dirty call (in a
network-friendly manner). Also, after such a failed dirty call for
a given Endpoint
and object identifier, any clean call
that is made for that same Endpoint
and object
identifier within a reasonable amount of time should pass
true
for the strong
argument, in case the
failed dirty call does eventually get delivered to the server after
such a clean call has been processed.
When the last remaining live remote reference with a given
Endpoint
and object identifier is detected to be
phantom reachable, the DGC client makes a clean call to the
server-side DGC implementation at that Endpoint
, with
that object identifier in the ids
argument. Clean
calls for several object identifiers at the same
Endpoint
may be batched as one clean call (such as
when multiple live remote references with the same
Endpoint
and different object identifiers are detected
to be phantom reachable at the same time).
If a clean call fails with a communication exception other than
a NoSuchObjectException
, the DGC client implementation
should make a reasonable effort to retry the clean call, in a
network-friendly manner, especially while the DGC client's lease
for the Endpoint
remains valid (or while dirty calls
for the same Endpoint
succeed).
Constructor and Description |
---|
BasicObjectEndpoint(Endpoint ep,
Uuid id,
boolean enableDGC)
Creates a new
BasicObjectEndpoint to reference a
remote object at the specified Endpoint with the
specified Uuid . |
Modifier and Type | Method and Description |
---|---|
boolean |
checkTrustEquivalence(Object obj)
Returns
true if the specified object (which is not
yet known to be trusted) is equivalent in trust, content, and
function to this known trusted object, and false
otherwise. |
boolean |
equals(Object obj)
Compares the specified object with this
BasicObjectEndpoint for equality. |
RemoteException |
executeCall(OutboundRequest call)
Synchronously executes a remote call in progress to the
identified remote object, so that the response can be read.
|
boolean |
getEnableDGC()
Returns
true if this
BasicObjectEndpoint participates in DGC and
false otherwise. |
Endpoint |
getEndpoint()
Returns the
Endpoint for the referenced remote
object. |
Uuid |
getObjectIdentifier()
Returns the object identifier for the referenced remote object.
|
int |
hashCode()
Returns the hash code value for this
BasicObjectEndpoint . |
OutboundRequestIterator |
newCall(InvocationConstraints constraints)
Returns an
OutboundRequestIterator to use to send
a new remote call to the referenced remote object using the
specified constraints. |
String |
toString()
Returns a string representation of this
BasicObjectEndpoint . |
public BasicObjectEndpoint(Endpoint ep, Uuid id, boolean enableDGC)
BasicObjectEndpoint
to reference a
remote object at the specified Endpoint
with the
specified Uuid
.ep
- the endpoint to send remote call requests for the
remote object toid
- the object identifier for the remote objectenableDGC
- flag indicating whether or not the
BasicObjectEndpoint
participates in DGCNullPointerException
- if e
or
id
is null
public OutboundRequestIterator newCall(InvocationConstraints constraints)
OutboundRequestIterator
to use to send
a new remote call to the referenced remote object using the
specified constraints.
The constraints must be the complete, absolute constraints for the remote call, combining any client and server constraints for the remote method being invoked, with no relative time constraints.
For each OutboundRequest
produced by the returned
OutboundRequestIterator
, after writing the request
data and before reading any response data, executeCall
must be invoked to execute the call.
This method first invokes newRequest
on this BasicObjectEndpoint
's
contained Endpoint
with the specified constraints
to obtain an OutboundRequestIterator
. It then
wraps the obtained iterator in another
OutboundRequestIterator
and returns the wrapped
iterator.
The methods of the returned
OutboundRequestIterator
behave as follows:
Returns
true
if this iterator supports making at least one more attempt to communicate the remote call, andfalse
otherwise.This method invokes
hasNext
on the underlying iterator and returns the result.The security context in which this method is invoked may be used for subsequent verification of security permissions; see the
next
method specification for more details.
Initiates an attempt to communicate the remote call to the referenced remote object.
This method invokes
next
on the underlying iterator to obtain anOutboundRequest
. Then it writes the object identifier of theBasicObjectEndpoint
that produced this iterator to the request's output stream by invokingUuid.write(OutputStream)
with the request output stream, and then it returns the request.Throws
NoSuchElementException
if this iterator does not support making another attempt to communicate the remote call (that is, ifhasNext
would returnfalse
).Throws
IOException
if anIOException
is thrown by the invocation ofnext
on the underlying iterator or by the subsequent I/O operations.Throws
SecurityException
if aSecurityException
is thrown by the invocation ofnext
on the underlying iterator or by the subsequent I/O operations.
newCall
in interface ObjectEndpoint
constraints
- the complete, absolute constraintsOutboundRequestIterator
to use to send
a new remote call to the referenced remote objectNullPointerException
- if constraints
is
null
public RemoteException executeCall(OutboundRequest call) throws IOException
This method should be passed an OutboundRequest
that was produced by an OutboundRequestIterator
returned from this object's newCall
method.
This method must be invoked after writing the request data to
and before reading any response data from the
OutboundRequest
.
If the remote call was successfully executed (such that the
response data may now be read) this method returns
null
. This method returns a non-null
RemoteException
to indicate a
RemoteException
that the remote call should fail
with. For example, if the referenced object does not exist at
the remote endpoint, a NoSuchObjectException
will be
returned. This method throws an IOException
for
other communication failures.
This method reads a byte from the response input stream of
call
. If an IOException
is thrown reading
the byte, that exception is thrown to the caller. If reading
the byte otherwise indicates EOF, an EOFException
is
thrown to the caller. If the byte is 0x00
, then
this method returns a NoSuchObjectException
indicating
that there is no remote object exported with the object
identifier at the remote endpoint. If the byte is
0x01
, then this method returns null
,
indicating that a remote object corresponding to the object
identifier and endpoint is exported, and thus the caller may
proceed to read the response of the remote call. If the byte
is any other value, this method returns an UnmarshalException
indicating that a protocol error occurred.
executeCall
in interface ObjectEndpoint
call
- the remote call to execute, produced by an
OutboundRequestIterator
that was returned from
newCall
null
on success, or a
RemoteException
if the remote call should fail
with that RemoteException
NullPointerException
- if call
is
null
IOException
- if an I/O exception occurs while performing
this operationpublic Endpoint getEndpoint()
Endpoint
for the referenced remote
object.Endpoint
for the referenced remote
objectpublic Uuid getObjectIdentifier()
public boolean getEnableDGC()
true
if this
BasicObjectEndpoint
participates in DGC and
false
otherwise.true
if this
BasicObjectEndpoint
participates in DGC and
false
otherwisepublic int hashCode()
BasicObjectEndpoint
.public boolean equals(Object obj)
BasicObjectEndpoint
for equality.
This method returns true
if and only if
BasicObjectEndpoint
,
enableDGC
flag in
the specified object are equal to the ones in this object, and
Endpoint
in the specified object has
the same class and is equal to the one in this object.
public boolean checkTrustEquivalence(Object obj)
true
if the specified object (which is not
yet known to be trusted) is equivalent in trust, content, and
function to this known trusted object, and false
otherwise.
This method returns true
if and only if
BasicObjectEndpoint
,
enableDGC
flag in
the specified object are equal to the ones in this object, and
Endpoint
is an instance of
TrustEquivalence
and invoking its
checkTrustEquivalence
method with the specified
object's Endpoint
returns true
.
checkTrustEquivalence
in interface TrustEquivalence
obj
- object to check that is not yet known to be trustedtrue
if the specified object (that is not yet
known to be trusted) is equivalent in trust, content, and function to
this known trusted object, and returns false
otherwise