use exclusive fromSequenceNumber in eventsByTag, #22145

* The reason is to have a consistent approach for Sequence and
  TimeBasedUUID, which are both intended as unique event identifiers.
* This means that you can use the offset that is returned in `EventEnvelope`
  as the `offset` parameter in a subsequent query.
This commit is contained in:
Patrik Nordwall 2017-01-16 11:13:45 +01:00
parent 4a9c753710
commit 8083c0bf4a
15 changed files with 101 additions and 34 deletions

View file

@ -51,7 +51,7 @@ class MyEventsByTagPublisher(tag: String, offset: Long, refreshInterval: FiniteD
private def statement() = connection.prepareStatement(
"""
SELECT id, persistent_repr FROM journal
WHERE tag = ? AND id >= ?
WHERE tag = ? AND id > ?
ORDER BY id LIMIT ?
""")

View file

@ -54,12 +54,24 @@ object PersistenceQueryDocSpec {
private val refreshInterval: FiniteDuration =
config.getDuration("refresh-interval", MILLISECONDS).millis
/**
* You can use `NoOffset` to retrieve all events with a given tag or retrieve a subset of all
* events by specifying a `Sequence` `offset`. The `offset` corresponds to an ordered sequence number for
* the specific tag. Note that the corresponding offset of each event is provided in the
* [[akka.persistence.query.EventEnvelope]], which makes it possible to resume the
* stream at a later point from a given offset.
*
* The `offset` is exclusive, i.e. the event with the exact same sequence number will not be included
* in the returned stream. This means that you can use the offset that is returned in `EventEnvelope`
* as the `offset` parameter in a subsequent query.
*/
override def eventsByTag(
tag: String, offset: Offset = Sequence(0L)): Source[EventEnvelope, NotUsed] = offset match {
case Sequence(offsetValue)
val props = MyEventsByTagPublisher.props(tag, offsetValue, refreshInterval)
Source.actorPublisher[EventEnvelope](props)
.mapMaterializedValue(_ => NotUsed)
case NoOffset => eventsByTag(tag, Sequence(0L)) //recursive
case _
throw new IllegalArgumentException("LevelDB does not support " + offset.getClass.getName + " offsets")
}

View file

@ -90,10 +90,14 @@ with the given ``tags``.
.. includecode:: code/docs/persistence/query/LeveldbPersistenceQueryDocSpec.scala#tagger
You can retrieve a subset of all events by specifying ``offset``, or use ``0L`` to retrieve all
events with a given tag. The ``offset`` corresponds to an ordered sequence number for the specific tag.
Note that the corresponding offset of each event is provided in the ``EventEnvelope``, which makes it possible
to resume the stream at a later point from a given offset.
You can use ``NoOffset`` to retrieve all events with a given tag or retrieve a subset of all
events by specifying a ``Sequence`` ``offset``. The ``offset`` corresponds to an ordered sequence number for
the specific tag. Note that the corresponding offset of each event is provided in the
``EventEnvelope``, which makes it possible to resume the stream at a later point from a given offset.
The ``offset`` is exclusive, i.e. the event with the exact same sequence number will not be included
in the returned stream. This means that you can use the offset that is returned in ``EventEnvelope``
as the ``offset`` parameter in a subsequent query.
In addition to the ``offset`` the ``EventEnvelope`` also provides ``persistenceId`` and ``sequenceNr``
for each event. The ``sequenceNr`` is the sequence number for the persistent actor with the