Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
math_tutor_dev
public_math_tutor
Commits
ab19628e
Commit
ab19628e
authored
Mar 23, 2026
by
Kantz
Browse files
Experimentelles Docker update für anderen containerstatus
parent
93c0d6c0
Changes
4
Hide whitespace changes
Inline
Side-by-side
math-tutor/backend/app/api/health.py
View file @
ab19628e
from
__future__
import
annotations
import
logging
from
threading
import
Lock
from
typing
import
Any
,
Dict
import
httpx
import
psycopg
from
fastapi
import
APIRouter
from
fastapi.responses
import
JSONResponse
import
app.config
as
config
router
=
APIRouter
()
logger
=
logging
.
getLogger
(
__name__
)
_READINESS_LOCK
=
Lock
()
_READINESS_STATE
:
Dict
[
str
,
Any
]
=
{
"status"
:
"starting"
}
def
set_readiness_starting
()
->
None
:
with
_READINESS_LOCK
:
_READINESS_STATE
.
clear
()
_READINESS_STATE
.
update
({
"status"
:
"starting"
})
def
set_readiness_ready
(
warmup
:
Dict
[
str
,
Any
]
|
None
=
None
)
->
None
:
with
_READINESS_LOCK
:
_READINESS_STATE
.
clear
()
_READINESS_STATE
.
update
({
"status"
:
"ready"
})
if
warmup
is
not
None
:
_READINESS_STATE
[
"warmup"
]
=
warmup
def
set_readiness_failed
(
detail
:
str
,
*
,
checks
:
Dict
[
str
,
Any
]
|
None
=
None
)
->
None
:
with
_READINESS_LOCK
:
_READINESS_STATE
.
clear
()
_READINESS_STATE
.
update
({
"status"
:
"failed"
,
"detail"
:
detail
})
if
checks
is
not
None
:
_READINESS_STATE
[
"checks"
]
=
checks
def
get_readiness_state
()
->
Dict
[
str
,
Any
]:
with
_READINESS_LOCK
:
return
dict
(
_READINESS_STATE
)
def
_check_ollama
()
->
dict
:
base_url
=
config
.
get_ollama_settings
().
base_url
.
rstrip
(
"/"
)
...
...
@@ -81,6 +113,14 @@ def health() -> Dict[str, Any]:
return
{
"status"
:
overall
,
"services"
:
services
}
@
router
.
get
(
"/api/health/ready"
)
def
readiness
()
->
Dict
[
str
,
Any
]:
state
=
get_readiness_state
()
if
state
.
get
(
"status"
)
==
"ready"
:
return
state
return
{
"status_code"
:
503
,
"content"
:
state
}
def
run_startup_checks
()
->
Dict
[
str
,
Any
]:
result
=
health
()
status
=
result
.
get
(
"status"
)
...
...
math-tutor/backend/app/main.py
View file @
ab19628e
...
...
@@ -13,12 +13,24 @@ logger = logging.getLogger(__name__)
@
asynccontextmanager
async
def
lifespan
(
_app
:
FastAPI
):
health
.
run_startup_checks
()
health
.
set_readiness_starting
()
startup_result
=
health
.
run_startup_checks
()
if
startup_result
.
get
(
"status"
)
!=
"ok"
:
health
.
set_readiness_failed
(
"Startup health checks degraded"
,
checks
=
startup_result
,
)
yield
return
try
:
warmup_timing
=
embedding_provider
.
warmup_embedder
()
logger
.
info
(
"Embedding warmup finished: %s"
,
warmup_timing
)
except
Exception
:
logger
.
exception
(
"Embedding warmup failed"
)
health
.
set_readiness_failed
(
"Embedding warmup failed"
)
else
:
health
.
set_readiness_ready
(
warmup
=
warmup_timing
)
yield
...
...
math-tutor/backend/test/health_readiness_unit_test.py
0 → 100644
View file @
ab19628e
import
json
import
unittest
from
app.api
import
health
from
fastapi.responses
import
JSONResponse
class
HealthReadinessUnitTest
(
unittest
.
TestCase
):
def
tearDown
(
self
)
->
None
:
health
.
set_readiness_starting
()
def
test_readiness_returns_503_while_starting
(
self
)
->
None
:
health
.
set_readiness_starting
()
response
=
health
.
readiness
()
self
.
assertIsInstance
(
response
,
JSONResponse
)
self
.
assertEqual
(
response
.
status_code
,
503
)
self
.
assertEqual
(
json
.
loads
(
response
.
body
),
{
"status"
:
"starting"
})
def
test_readiness_returns_200_when_ready
(
self
)
->
None
:
warmup
=
{
"total_warmup_ms"
:
123.45
}
health
.
set_readiness_ready
(
warmup
=
warmup
)
response
=
health
.
readiness
()
self
.
assertEqual
(
response
,
{
"status"
:
"ready"
,
"warmup"
:
warmup
})
def
test_readiness_returns_503_when_failed
(
self
)
->
None
:
checks
=
{
"status"
:
"degraded"
}
health
.
set_readiness_failed
(
"Embedding warmup failed"
,
checks
=
checks
)
response
=
health
.
readiness
()
self
.
assertIsInstance
(
response
,
JSONResponse
)
self
.
assertEqual
(
response
.
status_code
,
503
)
self
.
assertEqual
(
json
.
loads
(
response
.
body
),
{
"status"
:
"failed"
,
"detail"
:
"Embedding warmup failed"
,
"checks"
:
checks
,
},
)
if
__name__
==
"__main__"
:
unittest
.
main
()
math-tutor/docker/docker-compose.yml
View file @
ab19628e
...
...
@@ -7,6 +7,18 @@ services:
-
../backend/.env
expose
:
-
"
8000"
healthcheck
:
test
:
[
"
CMD"
,
"
python"
,
"
-c"
,
"
import
urllib.request;
urllib.request.urlopen('http://localhost:8000/api/health/ready')"
,
]
interval
:
5s
timeout
:
3s
retries
:
10
start_period
:
120s
restart
:
unless-stopped
volumes
:
-
./logs:/app/logs
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment