@@ -108,30 +108,31 @@ func (c *Controller) Process(ctx context.Context, delivery consumer.Delivery) er
108108 // Non-retryable: a malformed message will never succeed regardless of retries.
109109 return fmt .Errorf ("failed to deserialize build signal: %w" , err )
110110 }
111+ queueTag := metrics .NewTag ("queue" , sig .GetQueueName ())
111112
112113 store , err := c .stores .For (storage.Config {QueueName : sig .GetQueueName ()})
113114 if err != nil {
114- metrics .NamedCounter (c .metricsScope , _opName , "storage_resolve_errors" , 1 )
115+ metrics .NamedCounter (c .metricsScope , _opName , "storage_resolve_errors" , 1 , queueTag )
115116 // Non-retryable: a missing or unresolvable queue is a malformed message.
116117 return fmt .Errorf ("failed to resolve storage for queue %q: %w" , sig .GetQueueName (), err )
117118 }
118119
119120 build , err := c .loadBuild (ctx , store , sig .Id )
120121 if err != nil {
121- metrics .NamedCounter (c .metricsScope , _opName , "storage_errors" , 1 )
122+ metrics .NamedCounter (c .metricsScope , _opName , "storage_errors" , 1 , queueTag )
122123 return err
123124 }
124125
125126 request , err := c .loadRequest (ctx , store , build .RequestID )
126127 if err != nil {
127- metrics .NamedCounter (c .metricsScope , _opName , "storage_errors" , 1 )
128+ metrics .NamedCounter (c .metricsScope , _opName , "storage_errors" , 1 , queueTag )
128129 return err
129130 }
130131
131132 // The payload's queue must match the request's authoritative queue; a
132133 // mismatch is a malformed message. Non-retryable — reject to the DLQ.
133134 if sig .GetQueueName () != "" && sig .GetQueueName () != request .Queue {
134- metrics .NamedCounter (c .metricsScope , _opName , "queue_mismatch" , 1 )
135+ metrics .NamedCounter (c .metricsScope , _opName , "queue_mismatch" , 1 , queueTag )
135136 return fmt .Errorf ("payload queue %q does not match queue %q of request %s" , sig .GetQueueName (), request .Queue , request .ID )
136137 }
137138
@@ -167,7 +168,7 @@ func (c *Controller) Process(ctx context.Context, delivery consumer.Delivery) er
167168 }
168169
169170 if effective .IsTerminal () {
170- if err := c .finishRequest (ctx , store , & request , effective ); err != nil {
171+ if err := c .finishRequest (ctx , queueTag , store , & request , effective ); err != nil {
171172 return err
172173 }
173174 if err := c .publishRecord (ctx , request .ID , request .Queue ); err != nil {
@@ -208,18 +209,18 @@ func (c *Controller) Process(ctx context.Context, delivery consumer.Delivery) er
208209// the request non-terminal, so redelivery re-runs both steps and decrements again
209210// — transiently over-admitting by one until releaseBuildSlot's zero clamp
210211// reconverges, which is the failure mode this pipeline prefers.
211- func (c * Controller ) finishRequest (ctx context.Context , store storage.Storage , request * entity.Request , status entity.BuildStatus ) error {
212+ func (c * Controller ) finishRequest (ctx context.Context , queueTag metrics. Tag , store storage.Storage , request * entity.Request , status entity.BuildStatus ) error {
212213 if request .State .HasBuildOutcome () {
213214 return nil
214215 }
215216
216- if err := c .releaseBuildSlot (ctx , store , request .Queue ); err != nil {
217- metrics .NamedCounter (c .metricsScope , _opName , "storage_errors" , 1 )
217+ if err := c .releaseBuildSlot (ctx , queueTag , store , request .Queue ); err != nil {
218+ metrics .NamedCounter (c .metricsScope , _opName , "storage_errors" , 1 , queueTag )
218219 return err
219220 }
220221
221- if err := c .markOutcome (ctx , store , request , outcomeState (status )); err != nil {
222- metrics .NamedCounter (c .metricsScope , _opName , "storage_errors" , 1 )
222+ if err := c .markOutcome (ctx , queueTag , store , request , outcomeState (status )); err != nil {
223+ metrics .NamedCounter (c .metricsScope , _opName , "storage_errors" , 1 , queueTag )
223224 return err
224225 }
225226 return nil
@@ -243,7 +244,7 @@ func outcomeState(status entity.BuildStatus) entity.RequestState {
243244// conflicts. First writer wins: once any outcome is recorded a later caller leaves it
244245// alone, so duplicate builds for one request (which build.md accepts) cannot flip the
245246// verdict back and forth.
246- func (c * Controller ) markOutcome (ctx context.Context , store storage.Storage , request * entity.Request , state entity.RequestState ) error {
247+ func (c * Controller ) markOutcome (ctx context.Context , queueTag metrics. Tag , store storage.Storage , request * entity.Request , state entity.RequestState ) error {
247248 reqStore := store .GetRequestStore ()
248249
249250 for {
@@ -268,6 +269,7 @@ func (c *Controller) markOutcome(ctx context.Context, store storage.Storage, req
268269 updated .Version = newVersion
269270 * request = updated
270271 metrics .NamedCounter (c .metricsScope , _opName , "outcomes" , 1 ,
272+ queueTag ,
271273 metrics .NewTag ("state" , string (state )),
272274 )
273275 return nil
@@ -279,7 +281,7 @@ func (c *Controller) markOutcome(ctx context.Context, store storage.Storage, req
279281// (preserving concurrent updates), clamps at zero, and retries on version conflicts.
280282// Unlike process's unwind-path release this is not best-effort: the caller must not
281283// mark the request terminal if the slot was not freed, so a hard failure is returned.
282- func (c * Controller ) releaseBuildSlot (ctx context.Context , store storage.Storage , queueName string ) error {
284+ func (c * Controller ) releaseBuildSlot (ctx context.Context , queueTag metrics. Tag , store storage.Storage , queueName string ) error {
283285 queueStore := store .GetQueueStore ()
284286
285287 for {
@@ -300,7 +302,7 @@ func (c *Controller) releaseBuildSlot(ctx context.Context, store storage.Storage
300302 }
301303 return fmt .Errorf ("failed to release build slot for queue %s: %w" , queueName , err )
302304 }
303- metrics .NamedCounter (c .metricsScope , _opName , "slot_released" , 1 )
305+ metrics .NamedCounter (c .metricsScope , _opName , "slot_released" , 1 , queueTag )
304306 return nil
305307 }
306308}
0 commit comments