nolint:cyclop // TODO abstract user queues to reduce complexity here.
()
| 103 | |
| 104 | //nolint:cyclop // TODO abstract user queues to reduce complexity here. |
| 105 | func (s *scope) incQueued() error { |
| 106 | if s.user.queueCh == nil && s.clusterUser.queueCh == nil { |
| 107 | // Request queues in the current scope are disabled. |
| 108 | return s.inc() |
| 109 | } |
| 110 | |
| 111 | // Do not store `replica` and `cluster_node` in labels, since they have |
| 112 | // no sense for queue metrics. |
| 113 | labels := prometheus.Labels{ |
| 114 | "user": s.labels["user"], |
| 115 | "cluster": s.labels["cluster"], |
| 116 | "cluster_user": s.labels["cluster_user"], |
| 117 | } |
| 118 | |
| 119 | if s.user.queueCh != nil { |
| 120 | select { |
| 121 | case s.user.queueCh <- struct{}{}: |
| 122 | defer func() { |
| 123 | <-s.user.queueCh |
| 124 | }() |
| 125 | default: |
| 126 | // Per-user request queue is full. |
| 127 | // Give the request the last chance to run. |
| 128 | err := s.inc() |
| 129 | if err != nil { |
| 130 | userQueueOverflow.With(labels).Inc() |
| 131 | } |
| 132 | return err |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | if s.clusterUser.queueCh != nil { |
| 137 | select { |
| 138 | case s.clusterUser.queueCh <- struct{}{}: |
| 139 | defer func() { |
| 140 | <-s.clusterUser.queueCh |
| 141 | }() |
| 142 | default: |
| 143 | // Per-clusterUser request queue is full. |
| 144 | // Give the request the last chance to run. |
| 145 | err := s.inc() |
| 146 | if err != nil { |
| 147 | clusterUserQueueOverflow.With(labels).Inc() |
| 148 | } |
| 149 | return err |
| 150 | } |
| 151 | } |
| 152 | |
| 153 | // The request has been successfully queued. |
| 154 | queueSize := requestQueueSize.With(labels) |
| 155 | queueSize.Inc() |
| 156 | defer queueSize.Dec() |
| 157 | |
| 158 | // Try starting the request during the given duration. |
| 159 | sleep, deadline := s.calculateQueueDeadlineAndSleep() |
| 160 | return s.waitUntilAllowStart(sleep, deadline, labels) |
| 161 | } |
| 162 |