There was a subtle race condition here since we thread out across TaskHolder objects, not across OfferHolder objects when constructing tasks to submit to the master. This makes it possible that two buildTask calls are running at once, before either of them calls addMatchedTask on the offer holder. The former of those grabs ports to assign to a task, while the latter subtracts the assigned ports from the offer resources so they aren't used a second time. Obviously not safe to run in parallel :doh:. Moved that all into the acceptTask method and marked as synchronized
There was a subtle race condition here since we thread out across TaskHolder objects, not across OfferHolder objects when constructing tasks to submit to the master. This makes it possible that two
buildTask
calls are running at once, before either of them calls addMatchedTask on the offer holder. The former of those grabs ports to assign to a task, while the latter subtracts the assigned ports from the offer resources so they aren't used a second time. Obviously not safe to run in parallel :doh:. Moved that all into the acceptTask method and marked as synchronized