| 258 | } |
| 259 | |
| 260 | foreach (const Offer& offer, offers) { |
| 261 | const Resources taskResources = [this]() { |
| 262 | Resources resources = Resources::parse( |
| 263 | "cpus:" + stringify(CPUS_PER_TASK) + |
| 264 | ";mem:" + stringify(MEM_PER_TASK)).get(); |
| 265 | resources.allocate(framework.role()); |
| 266 | return resources; |
| 267 | }(); |
| 268 | |
| 269 | // Are there already `num_task` sleep tasks running? |
| 270 | // Having `num_task` sleeps running takes priority over dealing |
| 271 | // with maintenance. |
| 272 | bool needMoreSleep = sleepers.size() < num_tasks; |
| 273 | |
| 274 | // Is the agent in the offer less risky than our riskiest agent? |
| 275 | // i.e. The offered agent's planned downtime is farther away. |
| 276 | bool offeredAgentIsLessRisky = riskiestAgent.isSome() && |
| 277 | (!offer.has_unavailability() || |
| 278 | offer.unavailability().start().nanoseconds() > |
| 279 | sleepers[riskiestAgent.get()].unavailability.nanoseconds()); |
| 280 | |
| 281 | // Are we already running a task on this agent? |
| 282 | // This scheduler will only launch one task per agent. |
| 283 | bool offeredAgentIsOccupied = sleepers.contains(offer.agent_id()); |
| 284 | |
| 285 | // We only need to accept an offer if we do not have enough sleep |
| 286 | // tasks active, or the offer provides a better agent. |
| 287 | bool needToLaunchTask = !offeredAgentIsOccupied && |
| 288 | (needMoreSleep || offeredAgentIsLessRisky); |
| 289 | |
| 290 | Resources resources(offer.resources()); |
| 291 | |
| 292 | // Check if this offer is big enough and if we need to launch anything. |
| 293 | if (!resources.toUnreserved().contains(taskResources) || |
| 294 | !needToLaunchTask) { |
| 295 | Call call; |
| 296 | call.mutable_framework_id()->CopyFrom(framework.id()); |
| 297 | call.set_type(Call::DECLINE); |
| 298 | |
| 299 | Call::Decline* decline = call.mutable_decline(); |
| 300 | decline->add_offer_ids()->CopyFrom(offer.id()); |
| 301 | decline->mutable_filters()->set_refuse_seconds(600); |
| 302 | |
| 303 | mesos->send(call); |
| 304 | continue; |
| 305 | } |
| 306 | |
| 307 | // Keeping `num_tasks` running has higher priority than migrating tasks. |
| 308 | // We only migrate tasks if there are enough running tasks. |
| 309 | if (!needMoreSleep && offeredAgentIsLessRisky) { |
| 310 | LOG(INFO) << "Migrating task " << sleepers[riskiestAgent.get()].taskId |
| 311 | << " from " << riskiestAgent.get(); |
| 312 | |
| 313 | Call call; |
| 314 | call.mutable_framework_id()->CopyFrom(framework.id()); |
| 315 | call.set_type(Call::KILL); |
| 316 | |
| 317 | Call::Kill* kill = call.mutable_kill(); |
nothing calls this directly
no test coverage detected