Create solver page; add Dockerfile

This commit is contained in:
2022-06-06 13:46:22 -05:00
parent 9112d9fde5
commit ee767b9ebd
46 changed files with 712 additions and 76 deletions

View File

@@ -25,4 +25,5 @@ include("reports/products.jl")
include("reports/tr_emissions.jl")
include("reports/tr.jl")
include("reports/write.jl")
include("web/web.jl")
end

126
src/web/run.jl Normal file
View File

@@ -0,0 +1,126 @@
println("Initializing...")
using Logging
using Cbc
using JSON
using JuMP
using RELOG
function solve(root, filename)
ref_file = "$root/$filename"
optimizer = optimizer_with_attributes(
Cbc.Optimizer,
"seconds" => 900,
)
ref_solution, ref_model = RELOG.solve(
ref_file,
optimizer=optimizer,
return_model=true,
marginal_costs=false,
)
Libc.flush_cstdio()
flush(stdout)
sleep(1)
if length(ref_solution) == 0
return
end
RELOG.write_products_report(
ref_solution,
replace(ref_file, ".json" => "_products.csv"),
)
RELOG.write_plants_report(
ref_solution,
replace(ref_file, ".json" => "_plants.csv"),
)
RELOG.write_plant_outputs_report(
ref_solution,
replace(ref_file, ".json" => "_plant_outputs.csv"),
)
RELOG.write_plant_emissions_report(
ref_solution,
replace(ref_file, ".json" => "_plant_emissions.csv"),
)
RELOG.write_transportation_report(
ref_solution,
replace(ref_file, ".json" => "_tr.csv"),
)
RELOG.write_transportation_emissions_report(
ref_solution,
replace(ref_file, ".json" => "_tr_emissions.csv"),
)
isdir("$root/scenarios") || return
for filename in readdir("$root/scenarios")
scenario = "$root/scenarios/$filename"
endswith(filename, ".json") || continue
sc_solution = RELOG.resolve(
ref_model,
scenario,
optimizer=optimizer,
)
if length(sc_solution) == 0
return
end
RELOG.write_plants_report(
sc_solution,
replace(scenario, ".json" => "_plants.csv"),
)
RELOG.write_products_report(
sc_solution,
replace(scenario, ".json" => "_products.csv"),
)
RELOG.write_plant_outputs_report(
sc_solution,
replace(scenario, ".json" => "_plant_outputs.csv"),
)
RELOG.write_plant_emissions_report(
sc_solution,
replace(scenario, ".json" => "_plant_emissions.csv"),
)
RELOG.write_transportation_report(
sc_solution,
replace(scenario, ".json" => "_tr.csv"),
)
RELOG.write_transportation_emissions_report(
sc_solution,
replace(scenario, ".json" => "_tr_emissions.csv"),
)
end
end
function solve_recursive(path)
# Solve instances
for (root, dirs, files) in walkdir(path)
if occursin(r"scenarios"i, root)
continue
end
for filename in files
endswith(filename, ".json") || continue
solve(root, filename)
end
end
# Collect results
results = []
for (root, dirs, files) in walkdir(path)
for filename in files
endswith(filename, "_plants.csv") || continue
push!(
results,
joinpath(
replace(root, path => ""),
replace(filename, "_plants.csv" => ""),
),
)
end
end
open("$path/output.json", "w") do file
JSON.print(file, results)
end
run(`zip -r $path/output.zip $path`)
end
solve_recursive(ARGS[1])

66
src/web/web.jl Normal file
View File

@@ -0,0 +1,66 @@
import HTTP
import JSON
using Random
const ROUTER = HTTP.Router()
const PROJECT_DIR = joinpath(dirname(@__FILE__), "..", "..")
const STATIC_DIR = joinpath(PROJECT_DIR, "relog-web", "build", "static")
const JOBS_DIR = joinpath(PROJECT_DIR, "jobs")
function serve_file(req::HTTP.Request, filename)
if isfile(filename)
open(filename) do file
return HTTP.Response(200, read(file))
end
else
return HTTP.Response(404)
end
end
function submit(req::HTTP.Request)
# Generate random job id
job_id = lowercase(randstring(12))
# Create job folder
job_path = joinpath(JOBS_DIR, job_id)
mkpath(job_path)
# Write JSON file
case = JSON.parse(String(req.body))
open(joinpath(job_path, "case.json"), "w") do file
JSON.print(file, case)
end
# Run job
run(`bash -c "(julia --project=$PROJECT_DIR $PROJECT_DIR/src/web/run.jl $job_path 2>&1 | tee $job_path/solve.log) >/dev/null 2>&1 &"`)
response = Dict(
"job_id" => job_id,
)
return HTTP.Response(200, body = JSON.json(response))
end
function get_index(req::HTTP.Request)
return serve_file(req, joinpath(STATIC_DIR, "..", "index.html"))
end
function get_static(req::HTTP.Request)
return serve_file(req, joinpath(STATIC_DIR, req.target[9:end]))
end
function get_jobs(req::HTTP.Request)
return serve_file(req, joinpath(JOBS_DIR, req.target[7:end]))
end
HTTP.@register(ROUTER, "GET", "/static", get_static)
HTTP.@register(ROUTER, "GET", "/jobs", get_jobs)
HTTP.@register(ROUTER, "POST", "/submit", submit)
HTTP.@register(ROUTER, "GET", "/", get_index)
function web(host = "127.0.0.1", port = 8080)
@info "Launching web interface: http://$(host):$(port)/"
Base.exit_on_sigint(false)
HTTP.serve(ROUTER, host, port)
Base.exit_on_sigint(true)
end