| 1492 | |
| 1493 | |
| 1494 | void HierarchicalAllocatorProcess::updateInverseOffer( |
| 1495 | const SlaveID& slaveId, |
| 1496 | const FrameworkID& frameworkId, |
| 1497 | const Option<UnavailableResources>& unavailableResources, |
| 1498 | const Option<InverseOfferStatus>& status, |
| 1499 | const Option<Filters>& filters) |
| 1500 | { |
| 1501 | CHECK(initialized); |
| 1502 | |
| 1503 | Framework& framework = *CHECK_NOTNONE(getFramework(frameworkId)); |
| 1504 | Slave& slave = *CHECK_NOTNONE(getSlave(slaveId)); |
| 1505 | |
| 1506 | CHECK(slave.maintenance.isSome()) |
| 1507 | << "Agent " << slaveId |
| 1508 | << " (" << slave.info.hostname() << ") should have maintenance scheduled"; |
| 1509 | |
| 1510 | // NOTE: We currently implement maintenance in the allocator to be able to |
| 1511 | // leverage state and features such as the FrameworkSorter and OfferFilter. |
| 1512 | |
| 1513 | // We use a reference by alias because we intend to modify the |
| 1514 | // `maintenance` and to improve readability. |
| 1515 | Slave::Maintenance& maintenance = slave.maintenance.get(); |
| 1516 | |
| 1517 | // Only handle inverse offers that we currently have outstanding. If it is not |
| 1518 | // currently outstanding this means it is old and can be safely ignored. |
| 1519 | if (maintenance.offersOutstanding.contains(frameworkId)) { |
| 1520 | // We always remove the outstanding offer so that we will send a new offer |
| 1521 | // out the next time we schedule inverse offers. |
| 1522 | maintenance.offersOutstanding.erase(frameworkId); |
| 1523 | |
| 1524 | // If the response is `Some`, this means the framework responded. Otherwise |
| 1525 | // if it is `None` the inverse offer timed out or was rescinded. |
| 1526 | if (status.isSome()) { |
| 1527 | // For now we don't allow frameworks to respond with `UNKNOWN`. The caller |
| 1528 | // should guard against this. This goes against the pattern of not |
| 1529 | // checking external invariants; however, the allocator and master are |
| 1530 | // currently so tightly coupled that this check is valuable. |
| 1531 | CHECK_NE(status->status(), InverseOfferStatus::UNKNOWN); |
| 1532 | |
| 1533 | // If the framework responded, we update our state to match. |
| 1534 | maintenance.statuses[frameworkId].CopyFrom(status.get()); |
| 1535 | } |
| 1536 | } |
| 1537 | |
| 1538 | // No need to install filters if `filters` is none. |
| 1539 | if (filters.isNone()) { |
| 1540 | return; |
| 1541 | } |
| 1542 | |
| 1543 | // Create a refused inverse offer filter. |
| 1544 | Try<Duration> timeout = Duration::create(Filters().refuse_seconds()); |
| 1545 | |
| 1546 | if (filters->refuse_seconds() > Days(365).secs()) { |
| 1547 | LOG(WARNING) << "Using 365 days to create the refused inverse offer" |
| 1548 | << " filter because the input value is too big"; |
| 1549 | |
| 1550 | timeout = Days(365); |
| 1551 | } else if (filters->refuse_seconds() < 0) { |
nothing calls this directly
no test coverage detected