| 150 | } |
| 151 | |
| 152 | void received(const PromiseResponse& response) |
| 153 | { |
| 154 | if (response.has_type() && response.type() == |
| 155 | PromiseResponse::IGNORED) { |
| 156 | ignoresReceived++; |
| 157 | |
| 158 | // A quorum of replicas have ignored the request. |
| 159 | if (ignoresReceived >= quorum) { |
| 160 | LOG(INFO) << "Aborting explicit promise request because " |
| 161 | << ignoresReceived << " ignores received"; |
| 162 | |
| 163 | // If the "type" is PromiseResponse::IGNORED, the rest of the |
| 164 | // fields don't matter. |
| 165 | PromiseResponse result; |
| 166 | result.set_type(PromiseResponse::IGNORED); |
| 167 | |
| 168 | promise.set(result); |
| 169 | terminate(self()); |
| 170 | } |
| 171 | |
| 172 | return; |
| 173 | } |
| 174 | |
| 175 | responsesReceived++; |
| 176 | |
| 177 | if (isRejectedPromise(response)) { |
| 178 | // Failed to get the promise from a replica for this position |
| 179 | // because it has been promised to a proposer with a higher |
| 180 | // proposal number. The 'proposal' field in the response |
| 181 | // specifies the proposal number. It is found to be larger than |
| 182 | // the proposal number used in this phase. |
| 183 | if (highestNackProposal.isNone() || |
| 184 | highestNackProposal.get() < response.proposal()) { |
| 185 | highestNackProposal = response.proposal(); |
| 186 | } |
| 187 | } else if (highestNackProposal.isSome()) { |
| 188 | // We still want to wait for more potential NACK responses so we |
| 189 | // can return the highest proposal number seen but we don't care |
| 190 | // about any more ACK responses. |
| 191 | } else { |
| 192 | // The position has been promised to us so the 'proposal' field |
| 193 | // should match the proposal we sent in the request. |
| 194 | CHECK_EQ(response.proposal(), request.proposal()); |
| 195 | |
| 196 | if (response.has_action()) { |
| 197 | CHECK_EQ(response.action().position(), position); |
| 198 | if (response.action().has_learned() && response.action().learned()) { |
| 199 | // Received a learned action. Note that there is no checking |
| 200 | // that we get the _same_ learned action in the event we get |
| 201 | // multiple responses with learned actions, we just take the |
| 202 | // "first". In fact, there is a specific instance in which |
| 203 | // learned actions will NOT be the same! In this instance, |
| 204 | // one replica may return that the action is a learned no-op |
| 205 | // because it knows the position has been truncated while |
| 206 | // another replica (that hasn't learned the truncation yet) |
| 207 | // might return the actual action at this position. Picking |
| 208 | // either action is _correct_, since eventually we know this |
| 209 | // position will be truncated. Fun! |
nothing calls this directly
no test coverage detected