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 = "";}defmodule MyApp.Events.MbNotRewindableAuditEvent do use Chronicle.Events.EventType, id: "mb-not-rewindable-audit-event"
defstruct message: "", occurred_at: ""end
defmodule MyApp.ReadModels.MbNotRewindableAuditLog do use Chronicle.ReadModels.ReadModel, not_rewindable: true
defstruct id: "", message: "", timestamp: ""
from MyApp.Events.MbNotRewindableAuditEvent, set: [id: :event_source_id, message: :message, timestamp: :occurred_at]endimport { eventType, Guid, notRewindable, setFrom } from '@cratis/chronicle';
@eventType()export class MbNotRewindableAuditEvent { message = ''; occurredAt = new Date();}
@notRewindableexport class 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