| 30 | } // end anonymous namespace |
| 31 | |
| 32 | void |
| 33 | ParentSelectionStrategy::markParentDown(ParentResult *result, unsigned int fail_threshold, unsigned int retry_time) |
| 34 | { |
| 35 | time_t now; |
| 36 | pRecord *pRec, *parents = result->rec->selection_strategy->getParents(result); |
| 37 | int new_fail_count = 0; |
| 38 | |
| 39 | // Make sure that we are being called back with a |
| 40 | // result structure with a parent |
| 41 | ink_assert(result->result == PARENT_SPECIFIED); |
| 42 | if (result->result != PARENT_SPECIFIED) { |
| 43 | return; |
| 44 | } |
| 45 | // If we were set through the API we currently have not failover |
| 46 | // so just return fail |
| 47 | if (result->is_api_result()) { |
| 48 | return; |
| 49 | } |
| 50 | |
| 51 | ink_assert((result->last_parent) < numParents(result)); |
| 52 | pRec = (parents + result->last_parent); |
| 53 | |
| 54 | // If the parent has already been marked down, just increment |
| 55 | // the failure count. If this is the first mark down on a |
| 56 | // parent we need to both set the failure time and set |
| 57 | // count to one. It's possible for the count and time get out |
| 58 | // sync due there being no locks. Therefore the code should |
| 59 | // handle this condition. If this was the result of a retry, we |
| 60 | // must update move the failedAt timestamp to now so that we continue |
| 61 | // negative cache the parent |
| 62 | if (pRec->failedAt.load() == 0 || result->retry == true) { |
| 63 | // Reread the current time. We want this to be accurate since |
| 64 | // it relates to how long the parent has been down. |
| 65 | now = time(nullptr); |
| 66 | |
| 67 | // Mark the parent failure time. |
| 68 | pRec->failedAt = now; |
| 69 | |
| 70 | // If this is clean mark down and not a failed retry, we |
| 71 | // must set the count to reflect this |
| 72 | if (result->retry == false) { |
| 73 | new_fail_count = pRec->failCount = 1; |
| 74 | } |
| 75 | |
| 76 | Note("Parent %s marked as down %s:%d for request %s", (result->retry) ? "retry" : "initially", pRec->hostname, pRec->port, |
| 77 | result->url); |
| 78 | } else { |
| 79 | int old_count = 0; |
| 80 | now = time(nullptr); |
| 81 | |
| 82 | // if the last failure was outside the retry window, set the failcount to 1 |
| 83 | // and failedAt to now. |
| 84 | if ((pRec->failedAt.load() + retry_time) < now) { |
| 85 | // coverity[check_return] |
| 86 | pRec->failCount = 1; |
| 87 | pRec->failedAt = now; |
| 88 | } else { |
| 89 | old_count = pRec->failCount.fetch_add(1, std::memory_order_relaxed); |
no test coverage detected