Class SchemaVersionCounter
RegistryMetadata.revisionCount,
that advances every time the Type schema is written.
Why it exists. ClusterEventBus buys latency, not correctness: neither
of its channels guarantees delivery. A projection that missed an event would otherwise stay stale
forever, since nothing would retry until an unrelated change happened to occur. Comparing the
version a projection was built from against the current one turns that into a self-healing
condition, checked on a rare heartbeat rather than on every read.
Why it is persisted. Redis would lose the counter on a flush or a restart, leaving instances unable to tell that anything changed — or, worse, seeing it go backwards. The database holds it; Redis only a copy, to keep it cheap to read.
The increment is a single server-side update, atomic in the database, so concurrent increments from different instances cannot lose each other the way a read-modify-write would.
- Author:
- Luca Frosini (ISTI - CNR)
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final longReturned bygetCurrentVersion()when the counter cannot be read at all. -
Method Summary
Modifier and TypeMethodDescriptionstatic longReads the current counter value without advancing it.static longReturns the current version from its Redis copy, falling back to the database when the copy is absent and repopulating it.static longAdvances the counter by one, together with the counter of the model the written type belongs to, and returns the new value.
-
Field Details
-
UNKNOWN_VERSION
public static final long UNKNOWN_VERSIONReturned bygetCurrentVersion()when the counter cannot be read at all. Distinct from any real version, so a caller can tell "unknown" from "never incremented".- See Also:
-
-
Method Details
-
increment
Advances the counter by one, together with the counter of the model the written type belongs to, and returns the new value.Never throws: a failure to advance is logged and reported as
UNKNOWN_VERSION, so that a schema write is never failed by its own change-signalling. The cost of a missed increment is a projection rebuilding later than it could have, not incorrect data.- Parameters:
modelName- the model the written type belongs to, ornullto advance the global counter alone- Returns:
- the new version, or
UNKNOWN_VERSIONif it could not be advanced
-
getCurrentVersion
public static long getCurrentVersion()Reads the current counter value without advancing it.Never throws: an unreadable counter is reported as
UNKNOWN_VERSION, which a caller must treat as "cannot tell", not as "unchanged". A missing record means no schema write has ever been recorded, which is version zero.- Returns:
- the current version, or
UNKNOWN_VERSIONif it could not be read
-
getCurrentVersionFast
public static long getCurrentVersionFast()Returns the current version from its Redis copy, falling back to the database when the copy is absent and repopulating it.Exists because the version has to be consulted on every cached read in order to tell a current entry from a superseded one, and a database round trip per read would cost more than the cache saves. The database stays authoritative: Redis merely holds a copy.
- Returns:
- the current version, or
UNKNOWN_VERSIONif it cannot be determined
-