[Instances] Honor reserved instances (#3563)

* [Instances] Honor reserved instances

Logic to select next available instance id was incorrect.
The correct logic selected the max id + 1 or max reserved + 1, but then it would overwrite if we enabled recycling ids.
Additionally, it was incrementing the reserved ids and assigning ids to the max reserved id vice the next available.
Finally, it was running the logic twice.

* Fix updated SQL to use fmt
This commit is contained in:
JJ 2023-08-20 20:21:51 -04:00 committed by GitHub
parent a61f951d0e
commit c47644ea46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -131,85 +131,60 @@ bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version
bool Database::GetUnusedInstanceID(uint16 &instance_id) bool Database::GetUnusedInstanceID(uint16 &instance_id)
{ {
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances); uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
uint32 max = 32000; uint32 max_instance_id = 32000;
// sanity check reserved
if (max_reserved_instance_id >= max_instance_id) {
instance_id = 0;
return false;
}
// initial query - get max unused id above reserved
auto query = fmt::format( auto query = fmt::format(
"SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}", "SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}",
max_reserved_instance_id, max_reserved_instance_id,
max_reserved_instance_id max_reserved_instance_id
); );
// recycle instances - change query to get first unused id above reserved
if (RuleB(Instances, RecycleInstanceIds)) { if (RuleB(Instances, RecycleInstanceIds)) {
query = ( query = fmt::format(
SQL( SQL(
SELECT i.id + 1 AS next_available SELECT MIN(i.id + 1) AS next_available
FROM instance_list i FROM instance_list i
LEFT JOIN instance_list i2 ON i2.id = i.id + 1 LEFT JOIN instance_list i2 ON i.id + 1 = i2.id
WHERE i2.id IS NULL WHERE i.id > {}
ORDER BY i.id AND i2.id IS NULL;
LIMIT 0, 1; ),
RuleI(Instances, ReservedInstances)
)
); );
} }
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
// could not successfully query - bail out
if (!results.Success()) { if (!results.Success()) {
instance_id = 0; instance_id = 0;
return false; return false;
} }
// no instances running - assign first id above reserved
if (results.RowCount() == 0) { if (results.RowCount() == 0) {
instance_id = max_reserved_instance_id; instance_id = max_reserved_instance_id + 1;
return true; return true;
} }
auto row = results.begin(); auto row = results.begin();
if (Strings::ToInt(row[0]) <= max) { // check that id is within limits
if (Strings::ToInt(row[0]) <= max_instance_id) {
instance_id = Strings::ToInt(row[0]); instance_id = Strings::ToInt(row[0]);
return true; return true;
} }
if (instance_id < max_reserved_instance_id) { // unhandled situation - should not reach here
instance_id = max_reserved_instance_id; instance_id = 0;
return true; return false;
}
query = fmt::format("SELECT id FROM instance_list where id > {} ORDER BY id", max_reserved_instance_id);
results = QueryDatabase(query);
if (!results.Success()) {
instance_id = 0;
return false;
}
if (results.RowCount() == 0) {
instance_id = 0;
return false;
}
max_reserved_instance_id++;
for (auto row : results) {
if (max_reserved_instance_id < Strings::ToUnsignedInt(row[0])) {
instance_id = max_reserved_instance_id;
return true;
}
if (max_reserved_instance_id > max) {
instance_id = 0;
return false;
}
max_reserved_instance_id++;
}
instance_id = max_reserved_instance_id;
return true;
} }
bool Database::IsGlobalInstance(uint16 instance_id) bool Database::IsGlobalInstance(uint16 instance_id)