mirror of
https://github.com/zitadel/zitadel.git
synced 2025-07-01 23:48:31 +00:00

# Eventstore fixes - `event.Position` used float64 before which can lead to [precision loss](https://github.com/golang/go/issues/47300). The type got replaced by [a type without precision loss](https://github.com/jackc/pgx-shopspring-decimal) - the handler reported the wrong error if the current state was updated and therefore took longer to retry failed events. # Mirror fixes - max age of auth requests can be configured to speed up copying data from `auth.auth_requests` table. Auth requests last updated before the set age will be ignored. Default is 1 month - notification projections are skipped because notifications should be sent by the source system. The projections are set to the latest position - ensure that mirror can be executed multiple times
104 lines
2.8 KiB
Go
104 lines
2.8 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/jackc/pgx/v5/pgconn"
|
|
"github.com/zitadel/logging"
|
|
|
|
"github.com/zitadel/zitadel/internal/admin/repository/eventsourcing/view"
|
|
"github.com/zitadel/zitadel/internal/api/authz"
|
|
"github.com/zitadel/zitadel/internal/database"
|
|
"github.com/zitadel/zitadel/internal/eventstore"
|
|
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
|
|
handler2 "github.com/zitadel/zitadel/internal/eventstore/handler/v2"
|
|
"github.com/zitadel/zitadel/internal/static"
|
|
)
|
|
|
|
type Config struct {
|
|
Client *database.DB
|
|
Eventstore *eventstore.Eventstore
|
|
|
|
BulkLimit uint64
|
|
FailureCountUntilSkip uint64
|
|
TransactionDuration time.Duration
|
|
Handlers map[string]*ConfigOverwrites
|
|
ActiveInstancer interface {
|
|
ActiveInstances() []string
|
|
}
|
|
}
|
|
|
|
type ConfigOverwrites struct {
|
|
MinimumCycleDuration time.Duration
|
|
}
|
|
|
|
var projections []*handler.Handler
|
|
|
|
func Register(ctx context.Context, config Config, view *view.View, static static.Storage) {
|
|
if static == nil {
|
|
return
|
|
}
|
|
|
|
// make sure the slice does not contain old values
|
|
projections = nil
|
|
|
|
projections = append(projections, newStyling(ctx,
|
|
config.overwrite("Styling"),
|
|
static,
|
|
view,
|
|
))
|
|
}
|
|
|
|
func Projections() []*handler2.Handler {
|
|
return projections
|
|
}
|
|
|
|
func Start(ctx context.Context) {
|
|
for _, projection := range projections {
|
|
projection.Start(ctx)
|
|
}
|
|
}
|
|
|
|
func ProjectInstance(ctx context.Context) error {
|
|
for i, projection := range projections {
|
|
logging.WithFields("name", projection.ProjectionName(), "instance", authz.GetInstance(ctx).InstanceID(), "index", fmt.Sprintf("%d/%d", i, len(projections))).Info("starting admin projection")
|
|
for {
|
|
_, err := projection.Trigger(ctx)
|
|
if err == nil {
|
|
break
|
|
}
|
|
var pgErr *pgconn.PgError
|
|
errors.As(err, &pgErr)
|
|
if pgErr.Code != database.PgUniqueConstraintErrorCode {
|
|
return err
|
|
}
|
|
logging.WithFields("name", projection.ProjectionName(), "instance", authz.GetInstance(ctx).InstanceID()).WithError(err).Debug("admin projection failed because of unique constraint, retrying")
|
|
}
|
|
logging.WithFields("name", projection.ProjectionName(), "instance", authz.GetInstance(ctx).InstanceID(), "index", fmt.Sprintf("%d/%d", i, len(projections))).Info("admin projection done")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (config Config) overwrite(viewModel string) handler2.Config {
|
|
c := handler2.Config{
|
|
Client: config.Client,
|
|
Eventstore: config.Eventstore,
|
|
BulkLimit: uint16(config.BulkLimit),
|
|
RequeueEvery: 3 * time.Minute,
|
|
MaxFailureCount: uint8(config.FailureCountUntilSkip),
|
|
TransactionDuration: config.TransactionDuration,
|
|
ActiveInstancer: config.ActiveInstancer,
|
|
}
|
|
overwrite, ok := config.Handlers[viewModel]
|
|
if !ok {
|
|
return c
|
|
}
|
|
if overwrite.MinimumCycleDuration > 0 {
|
|
c.RequeueEvery = overwrite.MinimumCycleDuration
|
|
}
|
|
return c
|
|
}
|