Sponsored Link •
|
Summary
I am finishing up the remote LogManager monitoring facilities in my http://logman.jini.org project and I'd like to share some interesting details about the implemenation.
Advertisement
|
There are some interesting classes that might be useful for
other applications. I needed a streaming connection for the
log stream, so I created a RemoteSocketStream
class that is
deserialized as an InputStream
. Its
readObject(ObjectInputStream)
method will
make the connection back to the remote socket, and pass a
Uuid cookie back to id with the server.
The method signature that I added to the RemoteHandler
interface
is shown below.
public HandlerControl listenToLogger( FormatterFactory fact ) throws IOException, UnsupportedOperationException;Initially, the remote Handler is attached to the top level of the logger name space. This will cause all LogRecords of the appropriate Level in the tree of Loggers to be sent to the client.
HandlerControl
interface returned by listenToLogger(FormatterFactory)
provides the ability to adjust the
logging stream. It is defined as follows.
public interface HandlerControl { /** Get the logging data stream. */ public InputStream getInputStream() throws IOException; /** Set the log level of the remote {@link java.util.logging.Handler} */ public void setLogLevel( Level l ) throws IOException; /** Add a {@link java.util.logging.Logger} to the set of loggers being monitored */ public void addLogger( String name ) throws IOException; /** Remove a {@link java.util.logging.Logger} from the set of loggers being monitored */ public void removeLogger( String name ) throws IOException; /** Close the {@link java.util.logging.Logger} stream */ public void close() throws IOException; }There are of course many different ways to implement the actions of this interface. I want to talk about what I did because I think the implementation shows how mobile code and custom RPC mechanisms can be used to exploit connectivity between a client and service.
My implementation of the RemoteHandler.listenToLogger(FormatterFactory)
method returns a RemoteSocketStream
subclass called
HandlerSocketStream
.
The super class, RemoteSocketStream
, is a serializable
java.io.InputStream
subclass. The
deserialization code in
RemoteSocketStream.readObject(ObjectInputStream)
makes the Socket
connection back to the server so that
data can start streaming out to the remote client. The client need
only start reading from the InputStream
to see the logging stream.
HandlerControl
methods are layered on top of that Socket stream.
Since the path to the server is already in place, it is not necessary to use
an RMI interface for controlling the server end. Instead, I chose to send simple lines
of text to implement the actions of the HandlerControl
interface.
The remote socket reader, at the server, reads the lines of text comming back from the client and processes lines formatted as indicated below.
Result is that the HandlerControl implementation does not need to be an RMI proxy. Instead, it is a Serializable class that uses a socket connection back to the service to implement the methods of the interface.
The solution developed here solves this problem by having the client make the connection to the server. This allows the route from the server to the client to not be an issue. When you develop services that you need to remotely adminster in remote networks, this type of solution can simplify several issues.
RemoteSocketStream
class I've created. It allows you to use a bi-directional path between the client and server to make simple RPC activities possible. The
important thing to remember is that this works good for void method calls. But
for method calls that return values, you might have to recreate multi-threaded call and return handling, or insert synchronization to force isolation through synchronization.
It will depend on whether only one, or multiple threads might use this socket stream for traffic toward the server at the same time. In many cases there are no multi-threading issues, and you can stick synchronized
on the method declarations to force synchronization in case the usage changes.
This API has all void methods, so the only synchronization necessary is in the I/O operations toward the server. So that the complete String representing the command goes out in an atomic write operation.
Have an opinion? Readers have already posted 3 comments about this weblog entry. Why not add yours?
If you'd like to be notified whenever Gregg Wonderly adds a new entry to his weblog, subscribe to his RSS feed.
Gregg Wonderly graduated from Oklahoma State University in 1988 with an MS in COMSCI. His areas of concentration include Operating Systems and Languages. His first job was at the AT&T Bell Labs facilities in Naperville IL working on software retrofit for the 5ESS switch. He designed a procedure control language in the era of the development of Java with similar motivations that the Oak and then Java language development was driven by. Language design is still at the top of his list, but his focus tends to be on application languges layered on top of programming languages such as Java. Some just consider this API design, but there really is more to it! Gregg now works for Cyte Technologies Inc., where he does software engineering and design related to distributed systems in highly available environments. |
Sponsored Links
|