fix: enhance API key handling and logging in middleware

Refactor API key processing to improve clarity and reduce code 
duplication. Introduce detailed logging for schema updates and 
initializations, capturing relevant context information. Use 
background context for async operations to avoid blocking. 
Implement organization lookup logic in the WebSocket init 
function for consistent API key handling across connections.
This commit is contained in:
2025-11-20 08:09:00 +01:00
parent a9a47c1690
commit bb0c08be06
3 changed files with 69 additions and 6 deletions
+47 -5
View File
@@ -123,6 +123,13 @@ func (r *mutationResolver) UpdateSubGraph(ctx context.Context, input model.Input
// Publish schema update to subscribers
go func() {
services, lastUpdate := r.Cache.Services(orgId, input.Ref, "")
r.Logger.Info("Publishing schema update after subgraph change",
"ref", input.Ref,
"orgId", orgId,
"lastUpdate", lastUpdate,
"servicesCount", len(services),
)
subGraphs := make([]*model.SubGraph, len(services))
for i, id := range services {
sg, err := r.fetchSubGraph(context.Background(), id)
@@ -149,12 +156,21 @@ func (r *mutationResolver) UpdateSubGraph(ctx context.Context, input model.Input
}
// Publish to all subscribers of this ref
r.PubSub.Publish(input.Ref, &model.SchemaUpdate{
update := &model.SchemaUpdate{
Ref: input.Ref,
ID: lastUpdate,
SubGraphs: subGraphs,
CosmoRouterConfig: &cosmoConfig,
})
}
r.Logger.Info("Publishing schema update to subscribers",
"ref", update.Ref,
"id", update.ID,
"subGraphsCount", len(update.SubGraphs),
"cosmoConfigLength", len(cosmoConfig),
)
r.PubSub.Publish(input.Ref, update)
}()
return r.toGqlSubGraph(subGraph), nil
@@ -225,8 +241,15 @@ func (r *queryResolver) Supergraph(ctx context.Context, ref string, isAfter *str
// SchemaUpdates is the resolver for the schemaUpdates field.
func (r *subscriptionResolver) SchemaUpdates(ctx context.Context, ref string) (<-chan *model.SchemaUpdate, error) {
orgId := middleware.OrganizationFromContext(ctx)
r.Logger.Info("SchemaUpdates subscription started",
"ref", ref,
"orgId", orgId,
)
_, err := r.apiKeyCanAccessRef(ctx, ref, false)
if err != nil {
r.Logger.Error("API key cannot access ref", "error", err, "ref", ref)
return nil, err
}
@@ -235,12 +258,22 @@ func (r *subscriptionResolver) SchemaUpdates(ctx context.Context, ref string) (<
// Send initial state immediately
go func() {
// Use background context for async operation
bgCtx := context.Background()
services, lastUpdate := r.Cache.Services(orgId, ref, "")
r.Logger.Info("Preparing initial schema update",
"ref", ref,
"orgId", orgId,
"lastUpdate", lastUpdate,
"servicesCount", len(services),
)
subGraphs := make([]*model.SubGraph, len(services))
for i, id := range services {
sg, err := r.fetchSubGraph(ctx, id)
sg, err := r.fetchSubGraph(bgCtx, id)
if err != nil {
r.Logger.Error("fetch subgraph for initial update", "error", err)
r.Logger.Error("fetch subgraph for initial update", "error", err, "id", id)
continue
}
subGraphs[i] = &model.SubGraph{
@@ -262,12 +295,21 @@ func (r *subscriptionResolver) SchemaUpdates(ctx context.Context, ref string) (<
}
// Send initial update
ch <- &model.SchemaUpdate{
update := &model.SchemaUpdate{
Ref: ref,
ID: lastUpdate,
SubGraphs: subGraphs,
CosmoRouterConfig: &cosmoConfig,
}
r.Logger.Info("Sending initial schema update",
"ref", update.Ref,
"id", update.ID,
"subGraphsCount", len(update.SubGraphs),
"cosmoConfigLength", len(cosmoConfig),
)
ch <- update
}()
// Clean up subscription when context is done