From c493170e73506e974a0644452fc5a334c08171bc Mon Sep 17 00:00:00 2001 From: Jeffrey Armstrong Date: Wed, 7 Apr 2021 14:21:35 -0400 Subject: Fixed many issues related to reporting status. Initial debugging of titan upload handling. --- captain/api.f90 | 45 +++++++++++++++++++++++++----------------- captain/config.f90 | 5 +---- captain/db.f90 | 28 +++++++++++++++++++++++--- captain/external.f90 | 11 ++++++++++- captain/gemini.f90 | 15 ++++++++------ captain/levitating-captain.prj | 44 ++++++++++++++++++++--------------------- captain/response.f90 | 20 +++++++++++++++++++ common/jessl.f90 | 2 +- common/network.F90 | 2 -- common/protocol.f90 | 20 +++++++++---------- common/utilities.F90 | 11 ++++------- player/instructions.f90 | 21 +++++++++++++++++--- player/levitating-player.prj | 24 ++++++---------------- player/player.F90 | 7 +++++-- player/talking.f90 | 4 ++-- 15 files changed, 159 insertions(+), 100 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 diff --git a/common/jessl.f90 b/common/jessl.f90 index 223fd14..a03df09 100644 --- a/common/jessl.f90 +++ b/common/jessl.f90 @@ -208,7 +208,7 @@ contains implicit none type(c_ptr)::ssl - character, dimension(:), intent(inout)::buf + character, dimension(:), intent(out)::buf integer::ssl_read integer::bufsize diff --git a/common/network.F90 b/common/network.F90 index 860830b..f986275 100644 --- a/common/network.F90 +++ b/common/network.F90 @@ -238,8 +238,6 @@ implicit none type(sockaddr_in), target::sock_addr logical::connect - !print *, c_sizeof(sock_addr) - connect = (connect_c(int(sockfd, kind=c_int), & c_loc(sock_addr), & sockaddr_size) .eq. 0) diff --git a/common/protocol.f90 b/common/protocol.f90 index 3b4a8a3..38f2cf1 100644 --- a/common/protocol.f90 +++ b/common/protocol.f90 @@ -149,12 +149,11 @@ contains response_line_completed = .false. response_line = " " response_line_index = 0 - + bytes_received = retrieve_characters(conn%ssl, buffer) do while(bytes_received > 0) do i=1, bytes_received - if(.not. response_line_completed) then response_line_index = response_line_index + 1 response_line(response_line_index:response_line_index) = buffer(i) @@ -260,7 +259,7 @@ contains successes(3) = send_string(conn%ssl, ";mime=application/octet-stream", trimming=.false.) end if - write(file_length_text, *) file_length + write(file_length_text, '(I14)') file_length file_length_text = adjustl(file_length_text) successes(4) = send_string(conn%ssl, ";size="//trim(file_length_text)//c_carriage_return//c_new_line, trimming=.false.) @@ -268,10 +267,14 @@ contains total_written = 0 bytes_read = read_into_buffer(unit_number, buffer) + + Print *, "bytes read for sending: ", bytes_read + do while(bytes_read > 0) - bytes_written = ssl_write(conn%ssl, buffer) + bytes_written = ssl_write(conn%ssl, buffer(1:bytes_read)) total_written = total_written + bytes_written bytes_read = read_into_buffer(unit_number, buffer) + Print *, "bytes read for sending now: ", bytes_read, " and so far, we wrote", total_written end do if(total_written >= file_length) then @@ -344,10 +347,7 @@ contains character(*), intent(in)::path integer::past_protocol, first_slash, last_slash - - ! For debugging - ! Print *, "*** Requested path is '"//trim(path)//"'" - + past_protocol = index(current_url, "://") if(path(1:2) == "//") then @@ -388,9 +388,7 @@ contains logical, intent(in), optional::once integer::i,j - - ! Print *, "*** Replacement: string='"//trim(string)//"' Pattern='"//pattern//"'" - + i = index(string, pattern) do while(i > 0) j = i + len(pattern) ! First character after match diff --git a/common/utilities.F90 b/common/utilities.F90 index d4b7b81..cd32610 100644 --- a/common/utilities.F90 +++ b/common/utilities.F90 @@ -56,7 +56,7 @@ contains integer, intent(in)::unit_number integer, intent(in), dimension(8)::values - write(unit_number, '(I4, A1, I2, A1, I2, 1X, I2, A1, I2, A1, I2)') & + write(unit_number, '(I4, A1, I0.2, A1, I0.2, 1X, I2, A1, I0.2, A1, I0.2)') & values(1), "-", & values(2), "-", & values(3), & @@ -207,6 +207,7 @@ contains write(num_text, *) abs(rnum) fullpath = "/tmp/lv."//trim(adjustl(num_text))//".tmp" + !call write_log("My temp filename is: '"//trim(fullpath)//"'") #endif end function generate_temporary_filename @@ -239,9 +240,7 @@ contains length_estimate = len_trim(str) + len_trim(val) allocate(character(len=length_estimate) :: holding) holding = " " - - print *, trim(str) - + ! Find the field field_location = index(str, "{"//trim(field)//"}") if(field_location > 0) then @@ -253,9 +252,7 @@ contains str = holding end if - - print *, trim(str) - + deallocate(holding) end subroutine replace_field_text diff --git a/player/instructions.f90 b/player/instructions.f90 index 273c379..a3dc97a 100644 --- a/player/instructions.f90 +++ b/player/instructions.f90 @@ -34,9 +34,14 @@ contains character(len=:), allocatable::json_string_value logical::found - call j%get("idle", json_string_value, found) + call j%get("status", json_string_value, found) - work_available = .not. found + if(found) then + Print *, "Checkin status: "//json_string_value + work_available = (json_string_value /= "idle") + else + work_available = .false. + end if end function work_available @@ -140,7 +145,7 @@ contains character(*), intent(out)::label write(label, '(A6,I3,A2)') "tasks(", i, ")." - label = label//trim(component) + label = trim(label)//trim(component) end subroutine task_component @@ -242,6 +247,15 @@ contains call get_task_operation(j, i, operation) + Print *, "Task: ", i + Print *, "Operation: "//trim(operation) + + if(len_trim(operation) == 0) then + success = .false. + capture_filename => null() + return + end if + found = .true. capture_filename => null() @@ -326,6 +340,7 @@ contains task_count = get_task_count(j) + ! Remember to zero-index your json! do i = 1, task_count call get_status_url(job_id, i, url, status=STATUS_STARTING) diff --git a/player/levitating-player.prj b/player/levitating-player.prj index 8bfa9c8..3817ee4 100644 --- a/player/levitating-player.prj +++ b/player/levitating-player.prj @@ -8,22 +8,16 @@ "enabled":"1" },{ "filename":"../common/network.F90", - "enabled":"1", - "panel":1, - "open":"1" + "enabled":"1" },{ "filename":"../common/protocol.f90", - "enabled":"1", - "panel":1, - "open":"1" + "enabled":"1" },{ "filename":"../common/request.f90", "enabled":"1" },{ "filename":"../common/utilities.F90", - "enabled":"1", - "panel":1, - "open":"1" + "enabled":"1" },{ "filename":"../common/wsa.f90", "enabled":"0" @@ -35,9 +29,7 @@ "enabled":"1" },{ "filename":"endpoints.f90", - "enabled":"1", - "panel":1, - "open":"1" + "enabled":"1" },{ "filename":"instructions.f90", "enabled":"1", @@ -45,14 +37,10 @@ "open":"1" },{ "filename":"player.F90", - "enabled":"1", - "panel":1, - "open":"1" + "enabled":"1" },{ "filename":"talking.f90", - "enabled":"1", - "panel":1, - "open":"1" + "enabled":"1" },{ "filename":"tasks.f90", "enabled":"1" diff --git a/player/player.F90 b/player/player.F90 index f5e4055..bac6d6f 100644 --- a/player/player.F90 +++ b/player/player.F90 @@ -39,6 +39,7 @@ implicit none end if if(work_to_do) then + Print *, "Work Available" job_id = get_job_id_from_checkin(j_checkin) call get_instruction_name_from_checkin(j_checkin, instruction_name) @@ -46,6 +47,8 @@ implicit none instr_json_available = request_json(url, j_instructions) if(instr_json_available) then + Print *, "instructions available" + ! Task loop call perform_tasks(j_instructions, job_id) @@ -55,7 +58,7 @@ implicit none else #ifdef GNU - call sleep(50) + call sleep(20) #endif end if @@ -157,7 +160,7 @@ contains ! NOTE: will fail on Windows if(.not. associated(logfile)) then allocate(character(len=256) :: logfile) - logfile = "/tmp/levitating.log" + logfile = "/tmp/levitating-player.log" end if ! Assign this computer an identity if not explicitly specified diff --git a/player/talking.f90 b/player/talking.f90 index 9c9db05..733f463 100644 --- a/player/talking.f90 +++ b/player/talking.f90 @@ -23,7 +23,7 @@ contains mod_url = url open(newunit=unit_number, file=filename, status='UNKNOWN', & - access='STREAM', form='UNFORMATTED', iostat=istatus) + access='STREAM', form='FORMATTED', iostat=istatus) if(istatus == 0) then status_code = request_url(mod_url, unit_number, return_type) @@ -98,7 +98,7 @@ contains inquire(file=filename, size=file_size) - open(newunit=unit_number, file=trim(filename), status='UNKNOWN', & + open(newunit=unit_number, file=trim(filename), status='OLD', & access='STREAM', form='UNFORMATTED', iostat=istatus) if(istatus == 0) then -- cgit v1.2.3