Commit d8d9e8cf authored by AdamSimpson's avatar AdamSimpson
Browse files

Hmmm...This is more complicated than I thought

parent d8bdd7dc
Loading
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -5,28 +5,36 @@
#include "boost/optional.hpp"
#include <list>
#include <queue>
#include <set>

class BuilderQueue {
public:
    explicit BuilderQueue(asio::io_service &io_service) : io_service(io_service),
                                                          max_builders(1),
                                                          max_available_builders(max_builders)
                                                          max_available_builders(max_builders),
                                                          update_in_progress(false)
                                                          {}

    // Create a new queue reservation and return it to the requester
    Reservation& enter();

    // Attempt to process the queue after an event that adds/removes builders or requests
    void tick(asio::yield_context yield);
    void tick();
private:
    asio::io_service &io_service;

    // Hold reservations that are to be fulfilled
    std::list<Reservation> reservations;

    // List of currently available builders
    std::set<Builder> available_builders;

    // Maximum number of active and cached builders
    const std::size_t max_builders;

    // Maximum number of builders to spin and keep up in reserve
    const std::size_t max_available_builders;

    // Flag to determine if an update is already in progress
    bool update_in_progress;
};
 No newline at end of file
+45 −33
Original line number Diff line number Diff line
#include "BuilderQueue.h"
#include "Logger.h"
#include "OpenStackBuilder.h"
#include <set>

Reservation &BuilderQueue::enter() {
    reservations.emplace_back(io_service);
    return reservations.back();
}

// TODO handle error state builders
void BuilderQueue::tick(asio::yield_context yield) {
    // Update OpenStack builder list
void BuilderQueue::tick() {
    // Process pending reservations
    for (auto &reservation : reservations) {
        if (reservation.pending() && !available_builders.empty()) {
            reservation.ready(*available_builders.begin());
            available_builders.erase(available_builders.begin());
        }
    }



    // Update OpenStack by creating and removing builders as required
    // This section can take quite some time so is done in a coroutine
    if (!update_in_progress) {
        update_in_progress = true;
        asio::spawn(io_service,
                    [&](asio::yield_context yield) {
                        auto all_builders = OpenStackBuilder::get_builders(io_service, yield);
                        std::set<Builder> unavailable_builders;

@@ -20,20 +33,18 @@ void BuilderQueue::tick(asio::yield_context yield) {
                                unavailable_builders.insert(reservation.builder.get());
                            }
                            if (reservation.complete()) {
            asio::spawn(io_service,
                        [&](asio::yield_context yield) {
                                OpenStackBuilder::destroy(reservation.builder.get(), io_service, yield);
                        });
        }
                            };
                        }

                        // TODO handle error state builders - potentially in destroy script?

                        // Remove all completed reservations
                        reservations.remove_if([](const auto &res) {
                            return res.complete();
                        });

                        // Available_builders = all_builders - unavailable_builders
    std::set<Builder> available_builders;
                        std::set_difference(all_builders.begin(), all_builders.end(),
                                            unavailable_builders.begin(), unavailable_builders.end(),
                                            std::inserter(available_builders, available_builders.begin()));
@@ -42,10 +53,11 @@ void BuilderQueue::tick(asio::yield_context yield) {
                        auto open_slots = max_builders - all_builders.size();
                        auto open_available_slots = max_available_builders - available_builders.size();
                        auto request_count = std::min(open_slots, open_available_slots);
    for (int i = 0; i < request_count; i++) {
        asio::spawn(io_service,
                    [&](asio::yield_context yield) {
                        for (auto i = 0; i < request_count; i++) {
                            OpenStackBuilder::request_create(io_service, yield);
                        }
                        update_in_progress = false;
                    });
    }

}
 No newline at end of file
+4 −1
Original line number Diff line number Diff line
@@ -36,11 +36,14 @@ int main(int argc, char *argv[]) {
                    });

        // Start the queue which ticks at the specified interval
        boost::asio::deadline_timer timer(io_service);
        asio::spawn(io_service,
                    [&](asio::yield_context yield) {
                        for (;;) {
                            try {
                                builder_queue.tick(yield);
                                builder_queue.tick();
                                timer.expires_from_now(boost::posix_time::seconds(1));
                                timer.async_wait(yield);
                            } catch (std::exception &e) {
                                logger::write(std::string() + "Queue tick error: " + e.what());
                            }
+1 −1
Original line number Diff line number Diff line
@@ -3,4 +3,4 @@
# OpenStack credentials
source /home/queue/openrc.sh

openstack server delete $1
 No newline at end of file
openstack server delete --wait $1
 No newline at end of file
+1 −1
Original line number Diff line number Diff line
@@ -3,4 +3,4 @@
# OpenStack credentials
source /home/queue/openrc.sh

openstack server list -f json --name Builder
 No newline at end of file
openstack server list -f json --name "^Builder$" --status Active
 No newline at end of file
Loading