Skip to content

Commit dc4f4fe

Browse files
committed
fix: add events.go back
1 parent 1ff4b01 commit dc4f4fe

2 files changed

Lines changed: 137 additions & 6 deletions

File tree

graph/ent.resolvers.go

Lines changed: 4 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/events/events.go

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package events
2+
3+
import (
4+
"context"
5+
"log/slog"
6+
"strconv"
7+
"time"
8+
9+
"github.com/database-playground/backend-v2/ent"
10+
"github.com/database-playground/backend-v2/internal/metrics"
11+
"github.com/posthog/posthog-go"
12+
"go.opentelemetry.io/otel"
13+
"go.opentelemetry.io/otel/attribute"
14+
otelcodes "go.opentelemetry.io/otel/codes"
15+
"go.opentelemetry.io/otel/trace"
16+
)
17+
18+
var tracer = otel.Tracer("dbplay.events")
19+
20+
// EventService is the service for triggering events.
21+
type EventService struct {
22+
entClient *ent.Client
23+
posthogClient posthog.Client
24+
25+
handlers []EventHandler
26+
}
27+
28+
// NewEventService creates a new EventService.
29+
func NewEventService(entClient *ent.Client, posthogClient posthog.Client) *EventService {
30+
return &EventService{
31+
entClient: entClient,
32+
posthogClient: posthogClient,
33+
handlers: []EventHandler{NewPointsGranter(entClient, posthogClient)},
34+
}
35+
}
36+
37+
// Event is the event to be triggered.
38+
type Event struct {
39+
Type EventType
40+
Payload map[string]any
41+
UserID int
42+
}
43+
44+
// EventHandler is the handler for the event.
45+
//
46+
// You can think it as the callback of the event.
47+
type EventHandler interface {
48+
HandleEvent(ctx context.Context, event *ent.Event) error
49+
}
50+
51+
// TriggerEvent triggers an event.
52+
func (s *EventService) TriggerEvent(ctx context.Context, event Event) {
53+
ctx, span := tracer.Start(ctx, "TriggerEvent",
54+
trace.WithAttributes(
55+
attribute.String("event.type", string(event.Type)),
56+
attribute.Int("user.id", event.UserID),
57+
))
58+
defer span.End()
59+
60+
err := s.triggerEvent(ctx, event)
61+
if err != nil {
62+
span.SetStatus(otelcodes.Error, "Failed to trigger event")
63+
span.RecordError(err)
64+
slog.Error("failed to trigger event", "error", err)
65+
} else {
66+
span.SetStatus(otelcodes.Ok, "Event triggered successfully")
67+
}
68+
69+
if s.posthogClient != nil {
70+
span.AddEvent("posthog.send", trace.WithAttributes(
71+
attribute.String("event.type", string(event.Type)),
72+
attribute.Int("user.id", event.UserID),
73+
))
74+
slog.Debug("sending event to PostHog", "event_type", event.Type, "user_id", event.UserID)
75+
err = s.posthogClient.Enqueue(posthog.Capture{
76+
DistinctId: strconv.Itoa(event.UserID),
77+
Event: string(event.Type),
78+
Timestamp: time.Now(),
79+
Properties: event.Payload,
80+
})
81+
if err != nil {
82+
span.RecordError(err)
83+
slog.Error("failed to send event to PostHog", "error", err)
84+
}
85+
}
86+
}
87+
88+
// triggerEvent triggers an event synchronously.
89+
func (s *EventService) triggerEvent(ctx context.Context, event Event) error {
90+
ctx, span := tracer.Start(ctx, "triggerEvent",
91+
trace.WithAttributes(
92+
attribute.String("event.type", string(event.Type)),
93+
attribute.Int("user.id", event.UserID),
94+
))
95+
defer span.End()
96+
97+
span.AddEvent("database.event.create")
98+
eventEntity, err := s.entClient.Event.Create().
99+
SetType(string(event.Type)).
100+
SetPayload(event.Payload).
101+
SetUserID(event.UserID).
102+
SetTriggeredAt(time.Now()).
103+
Save(ctx)
104+
if err != nil {
105+
span.SetStatus(otelcodes.Error, "Failed to create event")
106+
span.RecordError(err)
107+
return err
108+
}
109+
110+
span.SetAttributes(attribute.Int("event.id", eventEntity.ID))
111+
112+
// Record metrics
113+
metrics.RecordEvent(string(event.Type))
114+
115+
span.AddEvent("handlers.processing", trace.WithAttributes(
116+
attribute.Int("handlers.count", len(s.handlers)),
117+
))
118+
119+
for i, handler := range s.handlers {
120+
span.AddEvent("handler.executing", trace.WithAttributes(
121+
attribute.Int("handler.index", i),
122+
))
123+
err := handler.HandleEvent(ctx, eventEntity)
124+
if err != nil {
125+
span.SetStatus(otelcodes.Error, "Failed to handle event")
126+
span.RecordError(err)
127+
return err
128+
}
129+
}
130+
131+
span.SetStatus(otelcodes.Ok, "Event triggered successfully")
132+
return nil
133+
}

0 commit comments

Comments
 (0)