Loading BuilderQueue/include/BuilderQueue.h +2 −2 Original line number Diff line number Diff line Loading @@ -10,8 +10,8 @@ class BuilderQueue { public: explicit BuilderQueue(asio::io_service &io_service) : io_service(io_service), max_builders(1), max_available_builders(max_builders), max_builders(20), max_available_builders(5), pending_requests(0) {} Loading BuilderQueue/src/BuilderQueue.cpp +9 −8 Original line number Diff line number Diff line Loading @@ -12,7 +12,12 @@ void BuilderQueue::tick(asio::yield_context yield) { auto all_builders = OpenStackBuilder::get_builders(io_service, yield); std::set<Builder> unavailable_builders; // Process reservations // Delete reservations that are completed reservations.remove_if([](const auto &reservation) { return reservation.finalized(); }); // Process existing reservations for (auto &reservation : reservations) { // Set unavailable builders, that is builders which are attached to a reservation if (reservation.builder) { Loading @@ -30,18 +35,13 @@ void BuilderQueue::tick(asio::yield_context yield) { } } // Delete reservations that are completed reservations.remove_if([](const auto &reservation) { return reservation.finalized(); }); // 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())); // Assign builders to any pending reservations // Assign any available builders to any pending reservations for (auto &reservation : reservations) { if (reservation.pending() && !available_builders.empty()) { reservation.ready(*available_builders.begin()); Loading @@ -50,7 +50,8 @@ void BuilderQueue::tick(asio::yield_context yield) { } // Request new builders if slots are open // Care must be taken as all_builders may include the the pending request before it's returned(open_slots, open_available_slots may be negative) // Care must be taken as all_builders may include a builder from a pending request that hasn't completely returned yet // that is to say open_slots, open_available_slots may be negative int open_slots = max_builders - all_builders.size() - pending_requests; int open_available_slots = max_available_builders - available_builders.size() - pending_requests; int request_count = std::min(open_slots, open_available_slots); Loading CMakeLists.txt +6 −1 Original line number Diff line number Diff line Loading @@ -53,7 +53,6 @@ set(HARDENING_FLAGS "-Wall -Wextra -fstack-protector-strong -D_FORTIFY_SOURCE=2 # https://github.com/boostorg/coroutine/issues/30 # -fsanitize=address,undefined -fno-sanitize=vptr -Wl,-z,noexecstack,-z,now,-z,relro,-z,nodlopen set_target_properties(BuilderQueue PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} ${HARDENING_FLAGS}") set_target_properties(BuilderQueue PROPERTIES LINK_FLAGS "${LINK_FLAGS} ${HARDENING_FLAGS}") set_target_properties(ContainerBuilder PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} ${HARDENING_FLAGS}") Loading @@ -73,4 +72,10 @@ target_link_libraries(BuilderQueue ${Boost_LIBRARIES}) target_link_libraries(ContainerBuilder ${Boost_LIBRARIES}) target_link_libraries(ContainerBuilderClient ${Boost_LIBRARIES}) # RPATH settings: https://cmake.org/Wiki/CMake_RPATH_handling SET(CMAKE_SKIP_BUILD_RPATH FALSE) SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) SET(CMAKE_INSTALL_RPATH "") SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) install(TARGETS BuilderQueue ContainerBuilder ContainerBuilderClient RUNTIME DESTINATION bin) No newline at end of file Client/main.cpp +62 −30 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ #include <boost/asio.hpp> #include <iostream> #include "Messenger.h" #include <memory> namespace asio = boost::asio; using asio::ip::tcp; Loading @@ -28,6 +28,34 @@ std::string queue_port() { } return std::string(env); } /* void display_spinner(asio::io_service &io_service, asio::yield_context &yield, bool display) { static bool should_display; static boost::asio::deadline_timer timer(io_service); should_display = display; auto expire_time = boost::posix_time::milliseconds(250); asio::spawn(io_service, [&](asio::yield_context yield) { while (should_display) { std::cout << "\b--" << std::flush; timer.expires_from_now(expire_time); timer.async_wait(yield); std::cout << "\b\\" << std::flush; timer.expires_from_now(expire_time); timer.async_wait(yield); std::cout << "\b|" << std::flush; timer.expires_from_now(expire_time); timer.async_wait(yield); timer.expires_from_now(expire_time); std::cout << "\b/" << std::flush; timer.async_wait(yield); } }); } */ int main(int argc, char *argv[]) { Loading @@ -41,32 +69,38 @@ int main(int argc, char *argv[]) { std::string definition_path(argv[1]); std::string container_path(argv[2]); std::cout << "Attempting to connect to BuilderQueue: " << queue_host() << ":" << queue_port() << std::endl; asio::io_service io_service; asio::spawn(io_service, [&](asio::yield_context yield) { std::cout << "Attempting to connect to BuilderQueue: " << queue_host() << ":" << queue_port() << std::endl; tcp::socket queue_socket(io_service); tcp::resolver queue_resolver(io_service); boost::system::error_code ec; asio::connect(queue_socket, queue_resolver.resolve({queue_host(), queue_port()})); asio::async_connect(queue_socket, queue_resolver.resolve({queue_host(), queue_port()}), yield); std::cout << "Connected to BuilderQueue: " << queue_host() << ":" << queue_port() << std::endl; Messenger queue_messenger(queue_socket); // Initiate a build request queue_messenger.send("checkout_builder_request"); queue_messenger.async_send("checkout_builder_request", yield); // Receive an available builder auto builder = queue_messenger.receive_builder(); // Wait on a builder from the queue auto builder = queue_messenger.async_receive_builder(yield); std::cout << "Attempting to connect to build host: " << builder.host << ":" << builder.port << std::endl; std::cout << "Attempting to connect to build host: " << builder.host << ":" << builder.port << std::endl; // Block until the initial connection to the builder is made tcp::socket builder_socket(io_service); tcp::resolver builder_resolver(io_service); do { asio::connect(builder_socket, builder_resolver.resolve({builder.host, builder.port}), ec); asio::async_connect(builder_socket, builder_resolver.resolve({builder.host, builder.port}), yield[ec]); } while (ec != boost::system::errc::success); std::cout << "Connected to builder host: " << builder.host << ":" << builder.port << std::endl; Loading @@ -74,14 +108,12 @@ int main(int argc, char *argv[]) { Messenger builder_messenger(builder_socket); // Once we're connected to the builder start the client process asio::spawn(io_service, [&](asio::yield_context yield) { std::cout << "Sending definition: " << definition_path << std::endl; // Send the definition file builder_messenger.async_send_file(definition_path, yield, true); std::cout << "Start reading builder output:" << std::endl; std::cout << "Start of Singularity builder output:" << std::endl; // Hide the cursor and disable buffering for cleaner output std::cout << "\e[?25l" << std::flush; Loading @@ -94,11 +126,11 @@ int main(int argc, char *argv[]) { } while (!line.empty()); // Read the container image std::cout << "Begin receive of container: " << container_path << std::endl; std::cout << "Sending finished container: " << container_path << std::endl; builder_messenger.async_receive_file(container_path, yield, true); std::cout << "End receive of container: " << container_path << std::endl; std::cout << "Container received: " << container_path << std::endl; // Inform the queue we're done queue_messenger.async_send(std::string("checkout_builder_complete"), yield); Loading Loading
BuilderQueue/include/BuilderQueue.h +2 −2 Original line number Diff line number Diff line Loading @@ -10,8 +10,8 @@ class BuilderQueue { public: explicit BuilderQueue(asio::io_service &io_service) : io_service(io_service), max_builders(1), max_available_builders(max_builders), max_builders(20), max_available_builders(5), pending_requests(0) {} Loading
BuilderQueue/src/BuilderQueue.cpp +9 −8 Original line number Diff line number Diff line Loading @@ -12,7 +12,12 @@ void BuilderQueue::tick(asio::yield_context yield) { auto all_builders = OpenStackBuilder::get_builders(io_service, yield); std::set<Builder> unavailable_builders; // Process reservations // Delete reservations that are completed reservations.remove_if([](const auto &reservation) { return reservation.finalized(); }); // Process existing reservations for (auto &reservation : reservations) { // Set unavailable builders, that is builders which are attached to a reservation if (reservation.builder) { Loading @@ -30,18 +35,13 @@ void BuilderQueue::tick(asio::yield_context yield) { } } // Delete reservations that are completed reservations.remove_if([](const auto &reservation) { return reservation.finalized(); }); // 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())); // Assign builders to any pending reservations // Assign any available builders to any pending reservations for (auto &reservation : reservations) { if (reservation.pending() && !available_builders.empty()) { reservation.ready(*available_builders.begin()); Loading @@ -50,7 +50,8 @@ void BuilderQueue::tick(asio::yield_context yield) { } // Request new builders if slots are open // Care must be taken as all_builders may include the the pending request before it's returned(open_slots, open_available_slots may be negative) // Care must be taken as all_builders may include a builder from a pending request that hasn't completely returned yet // that is to say open_slots, open_available_slots may be negative int open_slots = max_builders - all_builders.size() - pending_requests; int open_available_slots = max_available_builders - available_builders.size() - pending_requests; int request_count = std::min(open_slots, open_available_slots); Loading
CMakeLists.txt +6 −1 Original line number Diff line number Diff line Loading @@ -53,7 +53,6 @@ set(HARDENING_FLAGS "-Wall -Wextra -fstack-protector-strong -D_FORTIFY_SOURCE=2 # https://github.com/boostorg/coroutine/issues/30 # -fsanitize=address,undefined -fno-sanitize=vptr -Wl,-z,noexecstack,-z,now,-z,relro,-z,nodlopen set_target_properties(BuilderQueue PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} ${HARDENING_FLAGS}") set_target_properties(BuilderQueue PROPERTIES LINK_FLAGS "${LINK_FLAGS} ${HARDENING_FLAGS}") set_target_properties(ContainerBuilder PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} ${HARDENING_FLAGS}") Loading @@ -73,4 +72,10 @@ target_link_libraries(BuilderQueue ${Boost_LIBRARIES}) target_link_libraries(ContainerBuilder ${Boost_LIBRARIES}) target_link_libraries(ContainerBuilderClient ${Boost_LIBRARIES}) # RPATH settings: https://cmake.org/Wiki/CMake_RPATH_handling SET(CMAKE_SKIP_BUILD_RPATH FALSE) SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) SET(CMAKE_INSTALL_RPATH "") SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) install(TARGETS BuilderQueue ContainerBuilder ContainerBuilderClient RUNTIME DESTINATION bin) No newline at end of file
Client/main.cpp +62 −30 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ #include <boost/asio.hpp> #include <iostream> #include "Messenger.h" #include <memory> namespace asio = boost::asio; using asio::ip::tcp; Loading @@ -28,6 +28,34 @@ std::string queue_port() { } return std::string(env); } /* void display_spinner(asio::io_service &io_service, asio::yield_context &yield, bool display) { static bool should_display; static boost::asio::deadline_timer timer(io_service); should_display = display; auto expire_time = boost::posix_time::milliseconds(250); asio::spawn(io_service, [&](asio::yield_context yield) { while (should_display) { std::cout << "\b--" << std::flush; timer.expires_from_now(expire_time); timer.async_wait(yield); std::cout << "\b\\" << std::flush; timer.expires_from_now(expire_time); timer.async_wait(yield); std::cout << "\b|" << std::flush; timer.expires_from_now(expire_time); timer.async_wait(yield); timer.expires_from_now(expire_time); std::cout << "\b/" << std::flush; timer.async_wait(yield); } }); } */ int main(int argc, char *argv[]) { Loading @@ -41,32 +69,38 @@ int main(int argc, char *argv[]) { std::string definition_path(argv[1]); std::string container_path(argv[2]); std::cout << "Attempting to connect to BuilderQueue: " << queue_host() << ":" << queue_port() << std::endl; asio::io_service io_service; asio::spawn(io_service, [&](asio::yield_context yield) { std::cout << "Attempting to connect to BuilderQueue: " << queue_host() << ":" << queue_port() << std::endl; tcp::socket queue_socket(io_service); tcp::resolver queue_resolver(io_service); boost::system::error_code ec; asio::connect(queue_socket, queue_resolver.resolve({queue_host(), queue_port()})); asio::async_connect(queue_socket, queue_resolver.resolve({queue_host(), queue_port()}), yield); std::cout << "Connected to BuilderQueue: " << queue_host() << ":" << queue_port() << std::endl; Messenger queue_messenger(queue_socket); // Initiate a build request queue_messenger.send("checkout_builder_request"); queue_messenger.async_send("checkout_builder_request", yield); // Receive an available builder auto builder = queue_messenger.receive_builder(); // Wait on a builder from the queue auto builder = queue_messenger.async_receive_builder(yield); std::cout << "Attempting to connect to build host: " << builder.host << ":" << builder.port << std::endl; std::cout << "Attempting to connect to build host: " << builder.host << ":" << builder.port << std::endl; // Block until the initial connection to the builder is made tcp::socket builder_socket(io_service); tcp::resolver builder_resolver(io_service); do { asio::connect(builder_socket, builder_resolver.resolve({builder.host, builder.port}), ec); asio::async_connect(builder_socket, builder_resolver.resolve({builder.host, builder.port}), yield[ec]); } while (ec != boost::system::errc::success); std::cout << "Connected to builder host: " << builder.host << ":" << builder.port << std::endl; Loading @@ -74,14 +108,12 @@ int main(int argc, char *argv[]) { Messenger builder_messenger(builder_socket); // Once we're connected to the builder start the client process asio::spawn(io_service, [&](asio::yield_context yield) { std::cout << "Sending definition: " << definition_path << std::endl; // Send the definition file builder_messenger.async_send_file(definition_path, yield, true); std::cout << "Start reading builder output:" << std::endl; std::cout << "Start of Singularity builder output:" << std::endl; // Hide the cursor and disable buffering for cleaner output std::cout << "\e[?25l" << std::flush; Loading @@ -94,11 +126,11 @@ int main(int argc, char *argv[]) { } while (!line.empty()); // Read the container image std::cout << "Begin receive of container: " << container_path << std::endl; std::cout << "Sending finished container: " << container_path << std::endl; builder_messenger.async_receive_file(container_path, yield, true); std::cout << "End receive of container: " << container_path << std::endl; std::cout << "Container received: " << container_path << std::endl; // Inform the queue we're done queue_messenger.async_send(std::string("checkout_builder_complete"), yield); Loading