|
|
PoJoe
Features
|
Dynamic
Discovery |
Use Case
A server application
may be started on one of several
server hardware platforms. Although
each platform/server must be assigned
a separate IP address, it is unreasonable
for client applications to be changed
each time the server platform changes.
Similarly, if the server hardware
box fails, it is desirable from
a disaster recovery perspective
that the server application be quickly
started on a standby server and
that the client applications not
require reconfiguration.
Functional Summary
Dynamic discovery includes client
and server discovery components
that are embedded in the client
and server applications.
- The server component is assigned
an instance name before being
opened.
- Optionally, it may be assigned
a specific port address on which
to listen for remote TCP connections.
- When the server's discovery
component is opened, it begins
listening on an IP multicast group
for a "where-is" request
that matches its instance name.
Whenever a corresponding "where-is"
request is detected, the discovery
server component responds by notifiying
the client of the host address
and port number that should be
used for a connection.
Base Classes
org.pojoe.discovery.DiscoveryServer org.pojoe.discovery.DiscoveryClient
|
|
Paging
Fifos |
Use Case
An application employs
a fifo to handle the loosely coupled
flow of data between two application
threads (A and B). Most of the time,
the data provider (thread A) is
processing a moderate amount of
information that can be processed
quickly by the data consumer (thread
B).
There are peak periods during the
day when thread A generates data
that is orders of magnitude greater
than what can be handled by thread
B. If the information in the queue
were to remain memory resident,
the application could fail due to
a memory overflow.
Thread B is responsible for writing
information to a relational data
mart, and occassionally the DBMS
has failed or the DBMS has become
deadlocked. As a result, the application
was shut down. However, the data
still stored in the queue could
not be lost, and must be available
to be processed the next time the
application is started.
Functional Summary
Paging fifos are muti-threaded
fifo queues. The queues support
reading and writing of string objects,
or POJO objects that can be converted
into strings. There can be multiple
writers, but only a single reader.
- When the fifo is opened, it
can be provided an instance name.
If provided such a name, the data
contained in the queue will be
persisted in compressed format
when the queue is closed, and
will available the next time that
named fifo is opened simply by
utilizing the same instance name.
- Additionally, each queue has
a memory capacity threshold that
is configurable for each fifo.
Until that threshold is reached,
all the fifo elements are stored
in memory. Once the threshold
is reached, entries are paged
(written) to disk. This feature
enables applications to read and
write to the fifo without the
overhead of disk IO, but memory
will not be exhausted in cases
when the fifo size reaches what
is considered a maximum memory
threshold.
Base Classes
org.pojoe.queue.MQue org.pojoe.queue.PersistentMQue
|
|
Async
Peer to Peer |
Use case
A hub and spoke application
is consolidating multple sources
of data. The hub application is
essentially a singleton that is
provided an instance name of "datahub."
The hub is responsible for writing
all of the information provided
by the various hubs to a common
data repository. The data repository
supports both adds and updates,
and as a result the hub requires
that what is written was received
in fifo order.
Functional Summary
Peer to peer async
supports a loosely coupled interprocess
communication model.
- The data consumer node (reader)
is a multi-threaded class that
is provided a unique instance
name and is discoverable by that
name. (See Dynamic Discovery).
- The reader supports simultaneous
attachments by multiple data provider
(writers), and all the data written
to the reader is cached in a single
queue (see paging fifo).
- The discovery component set
is implemented in IP multicasting,
and the data flow is implemented
in reliable TCP/IP.
Typical Scenario
- When the hub is executed, it
instantiates a data discovery
server that first tests that there
is no other application calling
itself "datahub".
- If the discovery server finds
that there is one, it throws an
exception and exits.
- If there is no other instance
with that name, the discovery
server begins to listen for writer
spokes that want to attach to
"datahub".
- When a spoke attempt to find
the datahub, the discovery server
replies to the spoke with the
ip address and server port of
the datahub.
- The spoke node then creates
a TCP socket session with to the
hub, and begins passing strings
to the hub as data packets.
- At any time, the spoke or hub
can terminate the session
Base Classes
org.pojoe.netp2p.NetReader org.pojoe.netpsp.NetWriter
|
|
Thread
Bean |
Use Case
An workflow application
is designed to contain a set of
loosely coupled components that
execute as separate units of work
(threads).
The various components
are instantiated in a specific order
by a controller class that notifies
each thread when it must initialize
itself and then begin its own unique
iteratirve process. When the time
comes for the application to terminate,
each component is notified to perform
whatever cleanup is indicated, and
then to stop processing. Additionally,
if a component encounters a fatal
error situation, it is responsible
for terminating its processing and
notifying the application controller
of its termination.
Since there is more
than one stack within the application
(one for each thread), rather than
thowing exceptions, each component
uses a special multi-threaded mechanism
to communicate state information
and error conditions to the controller.
Base Class
org.pojoe.thread.Threadbean
|
|
Message
Pulsar |
Use Case
A server application
is executing on a remote host computer.
There is the need to monitor the
state of the application is real
time through some sort of graphics
monifor. There may be one or more
individuals that are monitoring
the sample application.
Functional Summary
- A threaded component periodically
wakes up (typically every 10 seconds)
and interrogates the state of
the application, accessing data
elements from various classes,
formatting the information into
a delimited string, and then publishing
the information to an IP multicast
group.
- Corresponding listeners that
subscribe to that multicast group
are passed the string, decode
the message, and pass the information
to a method that in turn writes
the data to labels and tables
on a graphic console.
Base Classes
org.pojoe.pulsar.MessagePulsar org.pojoe.pulsar.MessagePulsarListener
|
|
Simple
logs |
Use Case
In addition to logs
that identify warning and catastrophic
events, there is a need to generate
another set of readable logs that
are more than status oriented. Logs
might include entries for all rejected
records, all records in a pre-processed
state, or a chronology of significant
events. The data these logs contain
are useful for audit purposes, to
replicate an application run for
purposes of debugging, and for subsequent
regression testing releases of the
application.
Logs should be readable
by a text editor. They may or may
not contain a date and time stamp.
Functional Summary
- There are logs defined for logging
rejected records, safe storage
of data, application audit, generalized
errors, and for application-defined
usages.
- Logs can be directed either
to standard outputs (stderror,
stdout), or to files.
- The standard output log can
also be redirected to a scrollable
Swing container.
Base Class
org.pojoe.log.Logs
|
|
|
Copyright (c) 1999-2011 George White and
other contributors.
All rights reserved.
|
|
|
|
|
|