| 604 | } |
| 605 | |
| 606 | void Controller::OnVersionedRPCReturned(const CompletionInfo& info, |
| 607 | bool new_bthread, int saved_error) { |
| 608 | // TODO(gejun): Simplify call-ending code. |
| 609 | // Intercept previous calls |
| 610 | while (info.id != _correlation_id && info.id != current_id()) { |
| 611 | if (_unfinished_call && get_id(_unfinished_call->nretry) == info.id) { |
| 612 | if (!FailedInline()) { |
| 613 | // Continue with successful backup request. |
| 614 | break; |
| 615 | } |
| 616 | // Complete failed backup request. |
| 617 | _unfinished_call->OnComplete(this, _error_code, info.responded, false); |
| 618 | delete _unfinished_call; |
| 619 | _unfinished_call = NULL; |
| 620 | } |
| 621 | // Ignore all non-backup requests and failed backup requests. |
| 622 | _error_code = saved_error; |
| 623 | response_attachment().clear(); |
| 624 | CHECK_EQ(0, bthread_id_unlock(info.id)); |
| 625 | return; |
| 626 | } |
| 627 | |
| 628 | if ((!_error_code && _retry_policy == NULL) || |
| 629 | _current_call.nretry >= _max_retry) { |
| 630 | goto END_OF_RPC; |
| 631 | } |
| 632 | if (_error_code == EBACKUPREQUEST) { |
| 633 | if (NULL != _backup_request_policy && !_backup_request_policy->DoBackup(this)) { |
| 634 | // No need to do backup request. |
| 635 | _error_code = saved_error; |
| 636 | CHECK_EQ(0, bthread_id_unlock(info.id)); |
| 637 | return; |
| 638 | } |
| 639 | |
| 640 | // Reset timeout if needed |
| 641 | int rc = 0; |
| 642 | if (timeout_ms() >= 0) { |
| 643 | rc = bthread_timer_add( |
| 644 | &_timeout_id, |
| 645 | butil::microseconds_to_timespec(_deadline_us), |
| 646 | HandleTimeout, (void*)_correlation_id.value); |
| 647 | } |
| 648 | if (rc != 0) { |
| 649 | SetFailed(rc, "Fail to add timer"); |
| 650 | goto END_OF_RPC; |
| 651 | } |
| 652 | if (!SingleServer()) { |
| 653 | if (_accessed == NULL) { |
| 654 | _accessed = ExcludedServers::Create( |
| 655 | std::min(_max_retry, RETRY_AVOIDANCE)); |
| 656 | if (NULL == _accessed) { |
| 657 | SetFailed(ENOMEM, "Fail to create ExcludedServers"); |
| 658 | goto END_OF_RPC; |
| 659 | } |
| 660 | } |
| 661 | _accessed->Add(_current_call.peer_id); |
| 662 | } |
| 663 | // _current_call does not end yet. |
no test coverage detected