commons-dev mailing list archives

I'm writing tests, and getting ready to put some tentative documentation
together for the uuid code I'd like to contribute. I've made some changes
described below. (Note: I'm using
http://www.ietf.org/internet-drafts/draft-mealling-uuid-urn-02.txt for the
specification)
Version 1 uuid generation in java is much more challenging perhaps than in
native code for essentially three reasons:
- Time resolution
Java provides millisecond time resolution, the uuid spec calls for
100-nanosecond intervals since the Gregorian changeover epoch. The spec
allows for "artificial" clocking in systems that do not provide the required
time resolution. An additional challenge comes from the windows operating
system and low time resolution issues. The effective resolution on windows
can be from 1ms to reportedly 54ms. I create a NativeWin32ClockImpl
implementation of the Clock interface, but its performance was miserable
(~30 min for 11K timestamps), so not included.
- Persisting state
The uuid specification recommends persisting the clock sequence, node
identifier, and last uuid timestamp to stable storage. The spec offers some
hints of acceptable practices when writing to stable storage is not feasible
on every single uuid generation call due to performance concerns.
Additionally provisions are made for systems that do not have or can not use
stable storage. In java this is not necessarily an issue, except some
containers prevent file i/o, etc (which is for myself the first think that
comes to mind when I hear stable storage.)
- Device Wide Mutex's
The version 1 algorithm calls for obtaining a system wide lock during
uuid generation. Java virtual machines as far is know have no built in means
of working with a system wide mutex (some workarounds; such as opening a
socket, nio file locks, jni, are possible.) For java when multiple vm
instances are running, or multiple vm's in general are running the uuid
generator needs some way to know it is the only generator creating an id for
the given timestamp, clock sequence, node identifier (mac address) at that
instance.
So to address these issues I've created two new packages,
o.a.c.i.uuid.state, and o.a.c.i.uuid.clock, as well as an
o.a.c.i.uuid.NodeManager interface. Various implementations are possible to
work around the issues mentioned above. I've not used commons Discovery
before (hint, hint, code review), but the intention is to allow discovery to
locate the configured implementations.
The clock package:
Implementations of the o.a.c.i.uuid.clock.Clock interface may address the
time resolution issue in different ways (for example if a system has
available a java real-time library the implementer could use that.)
The state package:
Many diffent ways of addressing stable storage are possible, and the
container in which the code must execute may determine what implemation is
most appropriate. I've create 3 implementations; InMemoryOnlyImpl,
ReadOnlyResourceImpl, and ReadWriteFileImpl. More implementations are
possible; such as a jdbc, jndi, etc. [So long as some sort of locking is
create or used]
The NodeManager:
The NodeManager implementation I've worked on makes the assumption that each
jvm instance is assigned it's own node identifier (mac-address) Other
implementations of the node manager could attempt to use the same set of
node identifiers across vm's if they obtain a device wide lock; such as by
opening a socket, using a file lock, etc.
Other approaches to solving these issues are certainly possible. I could see
where one might publish an rmi service on a known port to service uuid
generation requests (the first vm to obtain the port would become the
server, any additional vm's would become clients.)
My intent is not to solve every possible implementation, but hopefully the
three major spi's allow for flexibility in version 1 generation, and provide
a few implementations that likely solve many of the requirements.
I'll use bugzilla to attach what I've got so that everyone interested can
review it. It'll not be in the form of patches yet (unless someone asks.) I
wanted to get some opinions prior to creating patches and submitting for
possible cvs commit. Additionally, I do have more tests todo and so I'm not
sure certain what expectation within a sandbox project is in terms of
stability of code. Some of the tests I want to do involve determining how
each implementation performs, as well as what I'd consider integration tests
(making sure the interaction between classes generates the correct events.)
Other notes:
With the number of classes this ends up being, I stopped prefixing
everything with UUIDXxxxXxx since it's redundant with the package name and
dropped the prefix from existing (this can be changed if there are
objections.)
I've added commons-codec as a dependency since the Hex.encode/decode methods
are so handy. I'm assuming we want to keep dependencies at a minimum. Hope
it's ok.
The zip I'll attach to bugzilla is out of synch with head, but depending on
the feedback I'll resynchronize prior to creating patches.
Look forward to your feedback
-TR
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org