diff options
Diffstat (limited to 'captain')
-rw-r--r-- | captain/api.f90 | 45 | ||||
-rw-r--r-- | captain/config.f90 | 5 | ||||
-rw-r--r-- | captain/db.f90 | 28 | ||||
-rw-r--r-- | captain/external.f90 | 11 | ||||
-rw-r--r-- | captain/gemini.f90 | 15 | ||||
-rw-r--r-- | captain/levitating-captain.prj | 44 | ||||
-rw-r--r-- | captain/response.f90 | 20 |
7 files changed, 114 insertions, 54 deletions
diff --git a/captain/api.f90 b/captain/api.f90 index 4594ba9..003a601 100644 --- a/captain/api.f90 +++ b/captain/api.f90 @@ -1,10 +1,11 @@ module api_handling +use iso_c_binding implicit none character(*), parameter::RESPONSE_JSON_OKAY = '{"status": "okay"}' character(*), parameter::RESPONSE_JSON_IDLE = '{"status": "idle"}' character(*), parameter::RESPONSE_JSON_WORK_AVAILABLE = & - '{"status": "pending", "job": {job_number}, "instruction": "{instruction_name}"}' + '{"status": "pending",'//c_new_line//' "job": {job_number},'//c_new_line//' "instruction": "{instruction_name}"}' contains @@ -46,6 +47,7 @@ contains if(ierr == 0) then if(req%query_string == "starting" .or. req%query_string == "inprogress") then call update_task_status(job_i, task_i, JOB_STATUS_WORKING) + call update_job_status(job_i, JOB_STATUS_WORKING) else if(req%query_string == "complete") then call update_task_status(job_i, task_i, JOB_STATUS_SUCCESS) else if(req%query_string == "failed") then @@ -60,6 +62,7 @@ contains use server_response use captain_db use special_filenames + use logging implicit none type(request), intent(in)::req @@ -92,7 +95,7 @@ contains resp%code = GEMINI_CODE_SUCCESS call resp%set_body_contents(RESPONSE_JSON_OKAY) - resp%body_mimetype = "application/json" + resp%body_mimetype = "text/plain" ! Checkin - /api/player/{name}/checkin.json else if(trim(req%component(2)) == "player" .and. trim(req%component(4)) == "checkin.json") then @@ -100,6 +103,10 @@ contains call req%path_component(3, player) player_i = get_player_id(player) + ! If we have a checkin, but the worker should have a job in progress, mark + ! the jobs as failed. + call mark_working_jobs_as_failed(player_i) + job_i = get_pending_job_for_player(player_i) if(job_i < 0) then resp%code = GEMINI_CODE_SUCCESS @@ -108,7 +115,8 @@ contains checkin_work_json => build_job_available_json(job_i) if(associated(checkin_work_json)) then resp%code = GEMINI_CODE_SUCCESS - call resp%set_body_contents(checkin_work_json, "application/json") + call write_log("Sending: "//trim(checkin_work_json)) + call resp%set_body_contents(trim(checkin_work_json), "text/gemini") deallocate(checkin_work_json) else resp%code = GEMINI_CODE_PERMFAIL @@ -123,7 +131,7 @@ contains if(associated(resp%body_filename)) then resp%temporary_file = .false. resp%code = GEMINI_CODE_SUCCESS - resp%body_mimetype = "application/json" + resp%body_mimetype = "text/plain" else resp%code = GEMINI_CODE_PERMFAIL end if @@ -135,6 +143,7 @@ contains function api_request_titan(req) result(resp) use server_response use special_filenames + use logging implicit none type(titan_request), intent(in)::req @@ -144,27 +153,25 @@ contains character(12)::job_text, task_text integer::job_id, task_num, ierr + character(64)::msg + fullpath => null() + call write_log("Titan request encountered") + ! Task - "/api/player/{name}/job/{jobid}/task/{task num}" if(trim(req%component(2)) == "player" .and. & trim(req%component(4)) == "job" .and. & trim(req%component(6)) == "task") then - call req%path_component(5, job_text) - read(job_text, *, iostat=ierr) job_id - if(ierr /= 0) then - resp%code = GEMINI_CODE_PERMFAIL - return - end if - - call req%path_component(5, task_text) - read(task_text, *, iostat=ierr) task_num - if(ierr /= 0) then - resp%code = GEMINI_CODE_PERMFAIL - return - end if + job_id = req%path_component_int(5) + + task_num = req%path_component_int(7) + + write(job_text, '(I6)') job_id + write(task_text, '(I6)') task_num + call write_log("Handling a task update for job "//trim(job_text)//" task "//trim(task_text)) call handle_task_request(req) fullpath => get_task_result_static_filename(job_id, task_num) @@ -174,11 +181,13 @@ contains if(associated(fullpath)) then ! Write the file + call write_log("Storing titan file to "//trim(fullpath)) + call req%write_to(fullpath) resp%code = GEMINI_CODE_SUCCESS call resp%set_body_contents(RESPONSE_JSON_OKAY) - resp%body_mimetype = "application/json" + resp%body_mimetype = "text/plain" else diff --git a/captain/config.f90 b/captain/config.f90 index 3d23011..6c622b4 100644 --- a/captain/config.f90 +++ b/captain/config.f90 @@ -144,10 +144,7 @@ contains call get_variable(line, cvariable) call get_value(line, cvalue) - - ! Debugging - ! Print *, trim(cvariable)//" => "//trim(cvalue) - + call assign_config(trim(cvariable), trim(cvalue)) end if diff --git a/captain/db.f90 b/captain/db.f90 index fa53774..a661fd4 100644 --- a/captain/db.f90 +++ b/captain/db.f90 @@ -589,12 +589,15 @@ contains implicit none integer, intent(in)::job_id - character(8)::update_date - character(10)::update_time + character(10)::update_date + character(8)::update_time + integer, dimension(8)::values type(sqlite3_stmt)::stmt - call date_and_time(date=update_date, time=update_time) + call date_and_time(values=values) + write(update_date, '(I4,A1,I0.2,A1,I0.2)') values(1), "-", values(2), "-", values(3) + write(update_time, '(I2,A1,I0.2,A1,I0.2)') values(5), ":", values(6), ":", values(7) if(stmt%prepare(db, "UPDATE jobs SET time=? WHERE id=?") == SQLITE_OK) then if(stmt%bind_text(1, update_date//" "//update_time) == SQLITE_OK .and. & stmt%bind_int(2, job_id) == SQLITE_OK) then @@ -697,6 +700,25 @@ contains end function get_pending_job_for_player + subroutine mark_working_jobs_as_failed(player) + implicit none + + integer, intent(in)::player + type(sqlite3_stmt)::stmt + + if(stmt%prepare(db, "UPDATE jobs SET status=? WHERE player=? AND status=? LIMIT 1") == SQLITE_OK) then + if(stmt%bind_int(1, JOB_STATUS_FAILURE) == SQLITE_OK .and. & + stmt%bind_int(2, player) == SQLITE_OK .and. & + stmt%bind_int(3, JOB_STATUS_WORKING) == SQLITE_OK) then + + call stmt%step_now() + + end if + end if + call stmt%finalize() + + end subroutine mark_working_jobs_as_failed + subroutine scan_instructions_for_db() use config use utilities diff --git a/captain/external.f90 b/captain/external.f90 index 97fa69c..db34a11 100644 --- a/captain/external.f90 +++ b/captain/external.f90 @@ -81,7 +81,16 @@ contains res = trim(res)//nl//nl//link - res = trim(res)//nl//"Running on "//trim(player)// & + select case(jobs(i)%status) + case(JOB_STATUS_SUCCESS, JOB_STATUS_FAILURE) + res = trim(res)//nl//"Completed on" + case(JOB_STATUS_PENDING) + res = trim(res)//nl//"Waiting to run on" + case(JOB_STATUS_WORKING) + res = trim(res)//nl//"Running on" + end select + + res = trim(res)//" "//trim(player)// & " - Last Update: "//trim(jobs(i)%time) end do diff --git a/captain/gemini.f90 b/captain/gemini.f90 index 8453db9..db0ac17 100644 --- a/captain/gemini.f90 +++ b/captain/gemini.f90 @@ -58,7 +58,7 @@ contains ierr = 0 i = 0 - do while(ierr == 0 .and. i < len(buffer)) + do while(ierr == 0 .and. i < 64) i = i + 1 read(unit_number, iostat=ierr) buffer(i) end do @@ -86,9 +86,9 @@ contains write(int_text, '(I8)') code line = trim(adjustl(int_text))//" "//trim(meta) - call write_log("Status line: "//trim(line)) + call write_log("Status line: '"//trim(line)//"'") - call write_string(ssl, trim(adjustl(int_text))//" "//trim(meta)//c_carriage_return//c_new_line) + call write_string(ssl, trim(line)//c_carriage_return//c_new_line) end subroutine write_status @@ -106,7 +106,7 @@ contains integer::buflen, written call write_status(ssl, GEMINI_CODE_SUCCESS, mimetype) - + buflen = read_into_buffer(unit_number, buf) do while(buflen > 0) written = ssl_write(ssl, buf(1:buflen)) @@ -267,8 +267,10 @@ contains if(trim(first) == 'api') then if(req%protocol == "gemini") then resp = api_request_gemini(req) + call write_log("resp filename is: '"//trim(resp%body_filename)//"'") else if(req%protocol == "titan") then call treq%init_from_request(req, ssl) + resp = api_request_titan(treq) end if else resp = external_request_gemini(req) @@ -292,15 +294,16 @@ contains form="unformatted", iostat=ioerror, access="stream") call write_file(ssl, rendered_unit, resp%body_mimetype) call write_log("File written") - close(rendered_unit) end select + call write_log("Cleanup") + call req%destroy() call resp%destroy() - + call write_log("shutdown") res = ssl_shutdown(ssl) res = ssl_free(ssl) res = ctx_free(ctx) diff --git a/captain/levitating-captain.prj b/captain/levitating-captain.prj index 6e48fb2..7202344 100644 --- a/captain/levitating-captain.prj +++ b/captain/levitating-captain.prj @@ -4,85 +4,85 @@ "Folders":[], "Name":"+common", "Files":[{ - "filename":"..\\common\\jessl.f90", + "filename":"../common/jessl.f90", "enabled":"1" },{ - "filename":"..\\common\\network.F90", + "filename":"../common/network.F90", "enabled":"1" },{ - "filename":"..\\common\\protocol.f90", + "filename":"../common/protocol.f90", "enabled":"1" },{ - "filename":"..\\common\\request.f90", + "filename":"../common/request.f90", "enabled":"1" },{ - "filename":"..\\common\\utilities.F90", + "filename":"../common/utilities.F90", "enabled":"1" },{ - "filename":"..\\common\\wsa.f90", + "filename":"../common/wsa.f90", "enabled":"0" }] },{ "Folders":[], "Name":"+example", "Files":[{ - "filename":".\\example\\levitating.conf", + "filename":"example/levitating.conf", "enabled":"1" }] },{ "Folders":[], "Name":"+sql", "Files":[{ - "filename":".\\sql\\create.sql", + "filename":"sql/create.sql", "enabled":"1" },{ - "filename":".\\sql\\scan_instructions.sh", + "filename":"sql/scan_instructions.sh", "enabled":"1" }] },{ "Folders":[], "Name":"+templates", "Files":[{ - "filename":".\\templates\\index.gmi", + "filename":"templates/index.gmi", "enabled":"1" }] }], "Name":"+levitating-captain (levitating-captain)", "Files":[{ - "filename":".\\api.f90", + "filename":"api.f90", "enabled":"1" },{ - "filename":".\\captian.f90", + "filename":"captian.f90", "enabled":"1" },{ - "filename":".\\config.f90", + "filename":"config.f90", "enabled":"1" },{ - "filename":".\\db.f90", + "filename":"db.f90", "enabled":"1" },{ - "filename":".\\external.f90", + "filename":"external.f90", "enabled":"1" },{ - "filename":".\\gemini.f90", + "filename":"gemini.f90", "enabled":"1" },{ - "filename":".\\launch.f90", + "filename":"launch.f90", "enabled":"1" },{ - "filename":".\\log.f90", + "filename":"log.f90", "enabled":"1" },{ - "filename":".\\response.f90", + "filename":"response.f90", "enabled":"1" },{ - "filename":".\\special.f90", + "filename":"special.f90", "enabled":"1" },{ - "filename":".\\sqlite.f90", + "filename":"sqlite.f90", "enabled":"1" },{ - "filename":".\\template.f90", + "filename":"template.f90", "enabled":"1" }] }, diff --git a/captain/response.f90 b/captain/response.f90 index 3526766..1c7a0b5 100644 --- a/captain/response.f90 +++ b/captain/response.f90 @@ -45,6 +45,7 @@ implicit none procedure :: destroy => request_destroy procedure :: last_component => request_last_component procedure :: path_component => request_component + procedure :: path_component_int => request_component_int procedure :: component => request_component_func end type request @@ -158,6 +159,25 @@ contains end subroutine request_component + + function request_component_int(self, i) result(res) + implicit none + + class(request) :: self + integer, intent(in)::i + integer :: res + + character(24)::restext + + restext = " " + + call self%path_component(i, restext) + + read(restext, '(I16)') res + + end function request_component_int + + function request_component_func(self, i) result(res) implicit none |