teldrive/internal/events/recorder.go

76 lines
1.4 KiB
Go

package events
import (
"context"
"github.com/tgdrive/teldrive/pkg/models"
"go.uber.org/zap"
"gorm.io/datatypes"
"gorm.io/gorm"
)
type EventType string
const (
OpCreate EventType = "file_create"
OpUpdate EventType = "file_update"
OpDelete EventType = "file_delete"
OpMove EventType = "file_move"
OpCopy EventType = "file_copy"
)
type Recorder struct {
db *gorm.DB
events chan models.Event
logger *zap.Logger
ctx context.Context
}
func NewRecorder(ctx context.Context, db *gorm.DB, logger *zap.Logger) *Recorder {
r := &Recorder{
db: db,
events: make(chan models.Event, 1000),
logger: logger,
ctx: ctx,
}
go r.processEvents()
return r
}
func (r *Recorder) Record(eventType EventType, userID int64, source *models.Source) {
evt := models.Event{
Type: string(eventType),
UserID: userID,
Source: datatypes.NewJSONType(source),
}
select {
case r.events <- evt:
default:
r.logger.Warn("event queue full, dropping event",
zap.String("type", string(eventType)),
zap.Int64("user_id", userID))
}
}
func (r *Recorder) processEvents() {
for {
select {
case <-r.ctx.Done():
return
case evt := <-r.events:
if err := r.db.Create(&evt).Error; err != nil {
r.logger.Error("failed to save event",
zap.Error(err),
zap.String("type", string(evt.Type)),
zap.Int64("user_id", evt.UserID))
}
}
}
}
func (r *Recorder) Shutdown() {
close(r.events)
}