aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--captain/api.f9045
-rw-r--r--captain/config.f905
-rw-r--r--captain/db.f9028
-rw-r--r--captain/external.f9011
-rw-r--r--captain/gemini.f9015
-rw-r--r--captain/levitating-captain.prj44
-rw-r--r--captain/response.f9020
-rw-r--r--common/jessl.f902
-rw-r--r--common/network.F902
-rw-r--r--common/protocol.f9020
-rw-r--r--common/utilities.F9011
-rw-r--r--player/instructions.f9021
-rw-r--r--player/levitating-player.prj24
-rw-r--r--player/player.F907
-rw-r--r--player/talking.f904
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