allow writers to starve. If this test passes on Java 5 and 6, we can
get rid of SynchronizedDatabaseComponent and merge
ReadWriteLockDatabaseComponent with DatabaseComponentImpl.
acceptable timestamp of subscribed messages. For a new subscription,
the timestamp is initialised to the current time, so a new subscriber
to a group will not immediately receive any messages. (Subscribing to
a group is therefore more like joining a mailing list than joining a
Usenet group - you only receive messages written after you joined.)
Once the database fills up and starts expiring messages, the
timestamps of subscriptions are updated so that contacts need not send
messages that would expire immediately. This is done using the
*approximate* timestamp of the oldest message in the database, to
avoid revealing the presence or absence of any particular message.
database - unlike transport properties, these are not shared with
contacts. For example, when using email as a transport, the address
for sending and receiving emails would be a transport property, while
the username and password for the email server would be transport
configuration details. Transport plugins can update their
configuration details atomically.
Also clarified the terminology for transport and subscription updates.
arrays, check it before allocating the buffer, and always specify the
maximum length when reading untrusted data - otherwise
CountingConsumer will reject the packet, but not before we've tried to
allocate a buffer of the specified size (up to 2 GB).
exception handling so that database connections aren't closed with
transactions in progress - this should make it possible to close the
database cleanly if an exception occurs.
received and sent batches, since batches sent to or received from
different contacts may contain identical lists of messages and
therefore have identical IDs.
this allows the caller to avoid creating an empty packet by delaying
creation of the packet's header and trailer until something's written
to the packet's body. Changed the return semantics of
DatabaseComponent.generateBatch(ContactId, BatchWriter,
Collection<MessageId>) so that the IDs of messages considered for
inclusion in the batch but no longer sendable are also returned - this
allows the caller to remove them from the set of requested IDs.
called when new messages are available, and a new method
hasSendableMessages(ContactId) that listeners can call to see whether
it's worth trying to create a batch.
to a contact, do not accept, offer, or send messages belonging to that
group to or from that contact, and do not list that group in
subscription updates sent to that contact.