diff --git a/scripts/install.sh b/scripts/install.sh index 30f8023200a156b958b4dbe5704a46419b4f553e..74459a78d9d8e29025ace4279d42ec2212f3071c 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +set -e + for flag in "$@"; do if [ "$flag" = "-h" -o "$flag" = "--help" ]; then echo "Command-line installer for LarvaTagger" @@ -278,9 +280,6 @@ EOF } if [ -n "$WITH_BACKEND" ]; then - if [ "`uname`" = "Darwin" ]; then - echo "WARNING: the default tagging backend is not supported by macOS" - fi if ! command -v python$PYTHON_VERSION &>/dev/null; then if command -v pyenv &>/dev/null; then [ `pyenv versions | grep $PYTHON_VERSION` ] || pyenv install $PYTHON_VERSION diff --git a/src/REST/Model.jl b/src/REST/Model.jl index d7122356c9149b52041b06dc85b14db29811a485..1450f65a93fc888d7865553390c92233b0633036 100644 --- a/src/REST/Model.jl +++ b/src/REST/Model.jl @@ -14,13 +14,15 @@ struct LTBackend root tokens lock + token_expiry end function LTBackend() root = Ref{AbstractString}("") tokens = Dict{String, Dict{String, Dict{String, Float64}}}() lock = ReentrantLock() - LTBackend(root, tokens, lock) + token_expiry = Ref{Union{Nothing, Real}}(nothing) + LTBackend(root, tokens, lock, token_expiry) end Base.lock(f::Function, backend::LTBackend) = lock(f, backend.lock) @@ -66,6 +68,7 @@ end function gettoken(lt_backend, backend_dir, model_instance) tagger = gettagger(lt_backend, backend_dir, model_instance) + resetdata(lt_backend) # perform server-wide maintenance return tagger.sandbox end @@ -88,6 +91,29 @@ function resetdata(lt_backend, backend_dir, model_instance, token, datadir=nothi nothing end +function resetdata(lt_backend, min_age) + isnothing(min_age) && return + @assert min_age isa Real + lock(lt_backend) do + for (backend_dir, instances) in pairs(lt_backend.tokens) + for (model_instance, tokens) in pairs(instances) + for (token, created) in pairs(copy(tokens)) + age = time() - created + if min_age <= age + @info "resetdata" backend_dir model_instance token age + tagger = gettagger(lt_backend, backend_dir, model_instance, token) + Taggers.resetdata(tagger) + pop!(tokens, token) + end + end + end + end + end + nothing +end + +resetdata(lt_backend) = resetdata(lt_backend, lt_backend.token_expiry[]) + function listfiles(lt_backend, backend_dir, model_instance, token, data_dir) tagger = gettagger(lt_backend, backend_dir, model_instance, token) dir = Taggers.datadir(tagger, data_dir) diff --git a/src/REST/Server.jl b/src/REST/Server.jl index 4bd2bf57fe951ea4acd3d8f00a1b6b403b06bdca..bda84596052d7f54ee77cbc273f6a7c5ef0a6d24 100644 --- a/src/REST/Server.jl +++ b/src/REST/Server.jl @@ -17,8 +17,9 @@ end # state const lt_backend = LTBackend() -function run_backend(root::AbstractString; kwargs...) +function run_backend(root::AbstractString, token_expiry=nothing; kwargs...) lt_backend.root[] = root + lt_backend.token_expiry[] = token_expiry run_backend(; kwargs...) end @@ -49,6 +50,14 @@ end end +@get "/reset-data/{min_age}" function ( + request, + min_age::Int, + ) + resetdata(lt_backend, min_age) +end + + @get "/reset-data/{backend_dir}/{model_instance}/{token}" function( request, backend_dir::String, diff --git a/test/rest_client.sh b/test/rest_client.sh index 9763454f8a6cb2ac4b5a3b7d71e10ef3c1fc308e..1213d5a78def51c709bf8a712fa815cb5a735f8b 100755 --- a/test/rest_client.sh +++ b/test/rest_client.sh @@ -24,7 +24,7 @@ julia "+$JULIA_VERSION" --project="${larvatagger_jl_project_root}" -q -e "using # run and background the backend server JULIA_PROJECT="${larvatagger_project_root}/TaggingBackends" \ julia "+$JULIA_VERSION" --project="${larvatagger_jl_project_root}" -i \ - -e "using LarvaTagger.REST.Server; run_backend(\"${larvatagger_project_root}\"; port=${lt_backend_port})" & + -e "using LarvaTagger.REST.Server; run_backend(\"${larvatagger_project_root}\", 300; port=${lt_backend_port})" & lt_backend_pid=$! # run the frontend server @@ -36,6 +36,8 @@ JULIA="julia +$JULIA_VERSION" ${larvatagger_jl_project_root}/scripts/larvatagger # expected: a predicted.label is generated and the GUI reloads # * load a second tracking data file (binary if first was ascii or vice versa), select another model instance, click again on "Autotag"; # expected: a new token was issued + similar outcome as previous step, with tracking data file and tagging model properly identified in the predicted.label file +# * wait for 5 min and click again on "Autotag"; +# expected: the data directories corresponding to the previous tokens are empty kill $lt_backend_pid wait $lt_backend_pid