Not Rewindable
Mark a projection as not rewindable (forward-only) using [NotRewindable]:
using Cratis.Chronicle.Events;using Cratis.Chronicle.Keys;using Cratis.Chronicle.Projections.ModelBound;
[EventType]public record MbNotRewindableAuditEvent(string Message, DateTimeOffset OccurredAt);
[NotRewindable]public record MbNotRewindableAuditLog( [Key] Guid Id,
[SetFrom<MbNotRewindableAuditEvent>(nameof(MbNotRewindableAuditEvent.Message))] string Message,
[SetFrom<MbNotRewindableAuditEvent>(nameof(MbNotRewindableAuditEvent.OccurredAt))] DateTimeOffset Timestamp);import io.cratis.chronicle.events.EventTypeimport io.cratis.chronicle.projections.FromEventimport io.cratis.chronicle.projections.NotRewindableimport io.cratis.chronicle.projections.SetFromimport io.cratis.chronicle.readModels.ReadModel
@EventTypedata class MbNotRewindableAuditEvent(val message: String, val occurredAt: String)
@ReadModel@FromEvent(MbNotRewindableAuditEvent::class)@NotRewindabledata class MbNotRewindableAuditLog( @SetFrom("message", MbNotRewindableAuditEvent::class) val message: String = "",
@SetFrom("occurredAt", MbNotRewindableAuditEvent::class) val timestamp: String = "")import io.cratis.chronicle.events.EventType;import io.cratis.chronicle.projections.FromEvent;import io.cratis.chronicle.projections.NotRewindable;import io.cratis.chronicle.projections.SetFrom;import io.cratis.chronicle.readModels.ReadModel;
@EventTyperecord MbNotRewindableAuditEvent(String message, String occurredAt) {}
@ReadModel@FromEvent(eventType = MbNotRewindableAuditEvent.class)@NotRewindableclass MbNotRewindableAuditLog { @SetFrom(propertyPath = "message", eventType = MbNotRewindableAuditEvent.class) public String message = "";
@SetFrom(propertyPath = "occurredAt", eventType = MbNotRewindableAuditEvent.class) public String timestamp = "";}Elixir does not support this workflow yet.import { eventType, Guid, notRewindable, readModel, setFrom } from '@cratis/chronicle';
@eventType()class MbNotRewindableAuditEvent { message = ''; occurredAt = new Date();}
@readModel()@notRewindableclass MbNotRewindableAuditLog { id: Guid = Guid.empty;
@setFrom(MbNotRewindableAuditEvent, 'message') message = '';
@setFrom(MbNotRewindableAuditEvent, 'occurredAt') timestamp = new Date();}When to use
Section titled “When to use”- Audit logs or append-only data
- Projections that should never be replayed from scratch
- Time-sensitive data where replay would be incorrect
Best practices
Section titled “Best practices”- Use for append-only scenarios where historical replay would be problematic
- Consider carefully as this removes the ability to rebuild the projection from scratch
- Ensure you have alternative recovery strategies if the projection becomes corrupted