mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 21:47:32 +00:00
feat(eventstore): increase parallel write capabilities (#5940)
This implementation increases parallel write capabilities of the eventstore. Please have a look at the technical advisories: [05](https://zitadel.com/docs/support/advisory/a10005) and [06](https://zitadel.com/docs/support/advisory/a10006). The implementation of eventstore.push is rewritten and stored events are migrated to a new table `eventstore.events2`. If you are using cockroach: make sure that the database user of ZITADEL has `VIEWACTIVITY` grant. This is used to query events.
This commit is contained in:
@@ -2,21 +2,27 @@ package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/api/service"
|
||||
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
||||
)
|
||||
|
||||
//BaseEvent represents the minimum metadata of an event
|
||||
var (
|
||||
_ Event = (*BaseEvent)(nil)
|
||||
)
|
||||
|
||||
// BaseEvent represents the minimum metadata of an event
|
||||
type BaseEvent struct {
|
||||
ID string
|
||||
EventType EventType `json:"-"`
|
||||
|
||||
aggregate Aggregate
|
||||
Agg *Aggregate
|
||||
|
||||
sequence uint64
|
||||
creationDate time.Time
|
||||
Seq uint64
|
||||
Pos float64
|
||||
Creation time.Time
|
||||
previousAggregateSequence uint64
|
||||
previousAggregateTypeSequence uint64
|
||||
|
||||
@@ -27,78 +33,91 @@ type BaseEvent struct {
|
||||
Data []byte `json:"-"`
|
||||
}
|
||||
|
||||
// Position implements Event.
|
||||
func (e *BaseEvent) Position() float64 {
|
||||
return e.Pos
|
||||
}
|
||||
|
||||
// EditorService implements Command
|
||||
func (e *BaseEvent) EditorService() string {
|
||||
return e.Service
|
||||
}
|
||||
|
||||
//EditorUser implements Command
|
||||
// EditorUser implements Command
|
||||
func (e *BaseEvent) EditorUser() string {
|
||||
return e.User
|
||||
}
|
||||
|
||||
//Type implements Command
|
||||
// Creator implements action
|
||||
func (e *BaseEvent) Creator() string {
|
||||
return e.EditorUser()
|
||||
}
|
||||
|
||||
// Type implements action
|
||||
func (e *BaseEvent) Type() EventType {
|
||||
return e.EventType
|
||||
}
|
||||
|
||||
//Sequence is an upcounting unique number of the event
|
||||
// Sequence is an upcounting unique number of the event
|
||||
func (e *BaseEvent) Sequence() uint64 {
|
||||
return e.sequence
|
||||
return e.Seq
|
||||
}
|
||||
|
||||
//CreationDate is the the time, the event is inserted into the eventstore
|
||||
// CreationDate is the the time, the event is inserted into the eventstore
|
||||
func (e *BaseEvent) CreationDate() time.Time {
|
||||
return e.creationDate
|
||||
return e.Creation
|
||||
}
|
||||
|
||||
//Aggregate represents the metadata of the event's aggregate
|
||||
func (e *BaseEvent) Aggregate() Aggregate {
|
||||
return e.aggregate
|
||||
// CreatedAt implements Event
|
||||
func (e *BaseEvent) CreatedAt() time.Time {
|
||||
return e.CreationDate()
|
||||
}
|
||||
|
||||
//Data returns the payload of the event. It represent the changed fields by the event
|
||||
// Aggregate implements action
|
||||
func (e *BaseEvent) Aggregate() *Aggregate {
|
||||
return e.Agg
|
||||
}
|
||||
|
||||
// Data returns the payload of the event. It represent the changed fields by the event
|
||||
func (e *BaseEvent) DataAsBytes() []byte {
|
||||
return e.Data
|
||||
}
|
||||
|
||||
//PreviousAggregateSequence implements EventReader
|
||||
func (e *BaseEvent) PreviousAggregateSequence() uint64 {
|
||||
return e.previousAggregateSequence
|
||||
// Revision implements action
|
||||
func (*BaseEvent) Revision() uint16 {
|
||||
return 0
|
||||
}
|
||||
|
||||
//PreviousAggregateTypeSequence implements EventReader
|
||||
func (e *BaseEvent) PreviousAggregateTypeSequence() uint64 {
|
||||
return e.previousAggregateTypeSequence
|
||||
// Unmarshal implements Event
|
||||
func (e *BaseEvent) Unmarshal(ptr any) error {
|
||||
if len(e.Data) == 0 {
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal(e.Data, ptr)
|
||||
}
|
||||
|
||||
//BaseEventFromRepo maps a stored event to a BaseEvent
|
||||
func BaseEventFromRepo(event *repository.Event) *BaseEvent {
|
||||
const defaultService = "zitadel"
|
||||
|
||||
// BaseEventFromRepo maps a stored event to a BaseEvent
|
||||
func BaseEventFromRepo(event Event) *BaseEvent {
|
||||
return &BaseEvent{
|
||||
aggregate: Aggregate{
|
||||
ID: event.AggregateID,
|
||||
Type: AggregateType(event.AggregateType),
|
||||
ResourceOwner: event.ResourceOwner.String,
|
||||
InstanceID: event.InstanceID,
|
||||
Version: Version(event.Version),
|
||||
},
|
||||
EventType: EventType(event.Type),
|
||||
creationDate: event.CreationDate,
|
||||
sequence: event.Sequence,
|
||||
previousAggregateSequence: event.PreviousAggregateSequence,
|
||||
previousAggregateTypeSequence: event.PreviousAggregateTypeSequence,
|
||||
Service: event.EditorService,
|
||||
User: event.EditorUser,
|
||||
Data: event.Data,
|
||||
Agg: event.Aggregate(),
|
||||
EventType: event.Type(),
|
||||
Creation: event.CreatedAt(),
|
||||
Seq: event.Sequence(),
|
||||
Service: defaultService,
|
||||
User: event.Creator(),
|
||||
Data: event.DataAsBytes(),
|
||||
Pos: event.Position(),
|
||||
}
|
||||
}
|
||||
|
||||
//NewBaseEventForPush is the constructor for event's which will be pushed into the eventstore
|
||||
// NewBaseEventForPush is the constructor for event's which will be pushed into the eventstore
|
||||
// the resource owner of the aggregate is only used if it's the first event of this aggregate type
|
||||
// afterwards the resource owner of the first previous events is taken
|
||||
func NewBaseEventForPush(ctx context.Context, aggregate *Aggregate, typ EventType) *BaseEvent {
|
||||
return &BaseEvent{
|
||||
aggregate: *aggregate,
|
||||
Agg: aggregate,
|
||||
User: authz.GetCtxData(ctx).UserID,
|
||||
Service: service.FromContext(ctx),
|
||||
EventType: typ,
|
||||
|
Reference in New Issue
Block a user