From b611ed199beaaaff79c1e2d24fa4b10965563058 Mon Sep 17 00:00:00 2001 From: Roberto Alsina Date: Sat, 6 Jul 2024 20:28:58 -0300 Subject: [PATCH] Streaming responses (WIP) --- src/commands/build.cr | 12 ++++++--- src/commands/scale.cr | 24 ++++++++++------- src/commands/status.cr | 20 +++++++++----- src/daemon/funko.cr | 61 +++++++++++++----------------------------- 4 files changed, 55 insertions(+), 62 deletions(-) diff --git a/src/commands/build.cr b/src/commands/build.cr index ac9a2c3..bf70395 100644 --- a/src/commands/build.cr +++ b/src/commands/build.cr @@ -47,14 +47,18 @@ module Faaso begin Log.info { "Uploading funko to #{FAASO_SERVER}" } - response = Crest.post( + Log.info { "Starting remote build:" } + Crest.post( url, {"funko.tgz" => File.open(tmp), "name" => "funko.tgz"}, user: "admin", password: "admin" - ) + ) do |response| + loop do + Log.info { response.body_io.gets } + break if response.body_io.closed? + end + end Log.info { "Build finished successfully." } - body = JSON.parse(response.body) - Log.info { body["output"] } rescue ex : Crest::InternalServerError Log.error(exception: ex) { "Error building funko #{funko.name} from #{funko.path}" } return 1 diff --git a/src/commands/scale.cr b/src/commands/scale.cr index bef35ea..1b6ae7f 100644 --- a/src/commands/scale.cr +++ b/src/commands/scale.cr @@ -28,21 +28,27 @@ module Faaso def remote(options, name, scale) : Int32 if !scale - response = Crest.get( + Crest.get( "#{FAASO_SERVER}funkos/#{name}/scale/", \ - user: "admin", password: "admin") + user: "admin", password: "admin") do |response| + loop do + Log.info { response.body_io.gets } + break if response.body_io.closed? + end + end else - response = Crest.post( + Crest.post( "#{FAASO_SERVER}funkos/#{name}/scale/", - {"scale" => scale}, user: "admin", password: "admin") + {"scale" => scale}, user: "admin", password: "admin") do |response| + loop do + Log.info { response.body_io.gets } + break if response.body_io.closed? + end + end end - body = JSON.parse(response.body) - Log.info { body["output"] } 0 rescue ex : Crest::InternalServerError - Log.error { "Error scaling funko #{name}" } - body = JSON.parse(ex.response.body) - Log.info { body["output"] } + Log.error(exception: ex) { "Error scaling funko #{name}" } 1 end diff --git a/src/commands/status.cr b/src/commands/status.cr index ab802d3..352b319 100644 --- a/src/commands/status.cr +++ b/src/commands/status.cr @@ -5,6 +5,11 @@ module Faaso funko = Funko::Funko.from_names([name])[0] status = funko.docker_status + if status.images.size == 0 + Log.error { "Unkown funko: #{name}" } + return 1 + end + Log.info { "Name: #{status.@name}" } Log.info { "Scale: #{status.scale}" } @@ -21,16 +26,17 @@ module Faaso end def remote(options, name) : Int32 - response = Crest.get( + Crest.get( "#{FAASO_SERVER}funkos/#{name}/status/", \ - user: "admin", password: "admin") - body = JSON.parse(response.body) - Log.info { body["output"] } + user: "admin", password: "admin") do |response| + loop do + Log.info { response.body_io.gets } + break if response.body_io.closed? + end + end 0 rescue ex : Crest::InternalServerError - Log.error { "Error scaling funko #{name}" } - body = JSON.parse(ex.response.body) - Log.info { body["output"] } + Log.error(exception: ex) { "Error scaling funko #{name}" } 1 end diff --git a/src/daemon/funko.cr b/src/daemon/funko.cr index 6574a7b..abfd904 100644 --- a/src/daemon/funko.cr +++ b/src/daemon/funko.cr @@ -8,39 +8,20 @@ module Funko # Get the funko's status get "/funkos/:name/status/" do |env| name = env.params.url["name"] - response = run_faaso(["status", name]) - - if response["exit_code"] != 0 - halt env, status_code: 500, response: response.to_json - else - response.to_json - end + run_faaso(["status", name], env) end # Get the funko's scale get "/funkos/:name/scale/" do |env| name = env.params.url["name"] - response = run_faaso(["scale", name]) - - if response["exit_code"] != 0 - halt env, status_code: 500, response: response.to_json - else - response.to_json - end + run_faaso(["scale", name], env) end # Set the funko's scale post "/funkos/:name/scale/" do |env| name = env.params.url["name"] scale = env.params.body["scale"].as(String) - response = run_faaso(["scale", name, scale]) - if response["exit_code"] != 0 - Log.error { response } - halt env, status_code: 500, response: response.to_json - else - Log.info { response } - response.to_json - end + run_faaso(["scale", name, scale], env) end # Build image for funko received as "funko.tgz" @@ -66,13 +47,7 @@ module Funko end # Build the thing - response = run_faaso(["build", tmp_dir.to_s, "--no-runtime"]) - - if response["exit_code"] != 0 - halt env, status_code: 500, response: response.to_json - else - response.to_json - end + run_faaso(["build", tmp_dir.to_s, "--no-runtime"], env) end # Endpoints for the web frontend @@ -150,21 +125,23 @@ module Funko "" end - # Helper to run faaso locally and get a response back - def run_faaso(args : Array(String)) + # Helper to run faaso locally and respond via env + def run_faaso(args : Array(String), env) : Bool Log.info { "Running faaso [#{args.join(", ")}, -l]" } - output = IO::Memory.new - status = Process.run( + Process.run( command: "faaso", args: args + ["-l"], # Always local in the server - output: output, - error: output, - ) - Log.debug { "faaso output: #{output}" } - result = { - "exit_code" => status.exit_code, - "output" => output.to_s, - } - result + ) do |process| + loop do + env.response.print process.output.gets(chomp: false) + env.response.flush + Fiber.yield + break if process.terminated? + end + p! process.error.peek + true + end + # FIXME: find a way to raise an exception on failure + # of the faaso process end end