| 375 | } |
| 376 | |
| 377 | int64_t LocalityAwareLoadBalancer::Weight::Update( |
| 378 | const CallInfo& ci, size_t index) { |
| 379 | const int64_t end_time_us = butil::gettimeofday_us(); |
| 380 | const int64_t latency = end_time_us - ci.begin_time_us; |
| 381 | BAIDU_SCOPED_LOCK(_mutex); |
| 382 | if (Disabled()) { |
| 383 | // The weight was disabled and will be removed soon, do nothing |
| 384 | // and the diff is 0. |
| 385 | return 0; |
| 386 | } |
| 387 | |
| 388 | _begin_time_sum -= ci.begin_time_us; |
| 389 | --_begin_time_count; |
| 390 | |
| 391 | if (latency <= 0) { |
| 392 | // time skews, ignore the sample. |
| 393 | return 0; |
| 394 | } |
| 395 | if (ci.error_code == 0) { |
| 396 | // Add a new entry |
| 397 | TimeInfo tm_info = { latency, end_time_us }; |
| 398 | if (!_time_q.empty()) { |
| 399 | tm_info.latency_sum += _time_q.bottom()->latency_sum; |
| 400 | } |
| 401 | _time_q.elim_push(tm_info); |
| 402 | } else { |
| 403 | // Accumulate into the last entry so that errors always decrease |
| 404 | // the overall QPS and latency. |
| 405 | // Note that the latency used is linearly mixed from the real latency |
| 406 | // (of an erroneous call) and the timeout, so that errors that are more |
| 407 | // unlikely to be solved by later retries are punished more. |
| 408 | // Examples: |
| 409 | // max_retry=0: always use timeout |
| 410 | // max_retry=1, retried=0: latency |
| 411 | // max_retry=1, retried=1: timeout |
| 412 | // max_retry=2, retried=0: latency |
| 413 | // max_retry=2, retried=1: (latency + timeout) / 2 |
| 414 | // max_retry=2, retried=2: timeout |
| 415 | // ... |
| 416 | int ndone = 1; |
| 417 | int nleft = 0; |
| 418 | if (ci.controller->max_retry() > 0) { |
| 419 | ndone = ci.controller->retried_count(); |
| 420 | nleft = ci.controller->max_retry() - ndone; |
| 421 | } |
| 422 | const int64_t err_latency = |
| 423 | (nleft * (int64_t)(latency * FLAGS_punish_error_ratio) |
| 424 | + ndone * ci.controller->timeout_ms() * 1000L) / (ndone + nleft); |
| 425 | |
| 426 | if (!_time_q.empty()) { |
| 427 | TimeInfo* ti = _time_q.bottom(); |
| 428 | ti->latency_sum += err_latency; |
| 429 | ti->end_time_us = end_time_us; |
| 430 | } else { |
| 431 | // If the first response is error, enlarge the latency as timedout |
| 432 | // since we know nothing about the normal latency yet. |
| 433 | const TimeInfo tm_info = { |
| 434 | std::max(err_latency, ci.controller->timeout_ms() * 1000L), |
no test coverage detected