Skip to content

Commit

Permalink
feat: Improve session state reliability
Browse files Browse the repository at this point in the history
- Instead of a str, the API returns a fixed set of available states.
  This makes handling in other application and the frontend easier.
- A separate attribute "preparation_state" is returned, indicating
  the status of the session preparation.
- Sessions no longer spawn deployments, Pods are directly created instead.
  This avoids unwanted restarts of containers.
- The `app` label on workloads has been replaced with `capellacollab/session-id`
- The logs are no longer considered for the session state.
  • Loading branch information
MoritzWeber0 committed Nov 8, 2024
1 parent b6f1bf2 commit d0a71b1
Show file tree
Hide file tree
Showing 27 changed files with 718 additions and 565 deletions.
20 changes: 0 additions & 20 deletions backend/capellacollab/sessions/injection.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@
# SPDX-License-Identifier: Apache-2.0

import logging
import re

import requests

from capellacollab import core
from capellacollab.config import config

from . import operators

log = logging.getLogger(__name__)


Expand Down Expand Up @@ -45,20 +42,3 @@ def _get_last_seen(idletime: int | float) -> str:
return f"{round(idlehours, 2)} hrs ago"

return f"{idletime:.0f} mins ago"


def determine_session_state(session_id: str) -> str:
state = operators.get_operator().get_session_state(session_id)

if state in ("Started", "BackOff"):
try:
logs = operators.get_operator().get_session_logs(
session_id, container="session-preparation"
)
logs += operators.get_operator().get_session_logs(session_id)
res = re.search(r"(?s:.*)^---(.*?)---$", logs, re.MULTILINE)
if res:
return res.group(1)
except Exception:
log.exception("Could not parse log")
return state
27 changes: 25 additions & 2 deletions backend/capellacollab/sessions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from capellacollab.core import database
from capellacollab.core import models as core_models
from capellacollab.core import pydantic as core_pydantic
from capellacollab.sessions import operators
from capellacollab.tools import models as tools_models
from capellacollab.users import models as users_models

Expand Down Expand Up @@ -69,6 +70,23 @@ class SessionSharing(core_pydantic.BaseModel):
created_at: datetime.datetime


class SessionPreparationState(enum.Enum):
RUNNING = "Running"
COMPLETED = "Completed"
FAILED = "Failed"
PENDING = "Pending"
NOT_FOUND = "NotFound"
UNKNOWN = "Unknown"


class SessionState(enum.Enum):
RUNNING = "Running"
TERMINATED = "Terminated"
PENDING = "Pending"
NOT_FOUND = "NotFound"
UNKNOWN = "Unknown"


class Session(core_pydantic.BaseModel):
id: str
type: SessionType
Expand All @@ -77,7 +95,10 @@ class Session(core_pydantic.BaseModel):

version: tools_models.ToolVersionWithTool

state: str = pydantic.Field(default="UNKNOWN")
preparation_state: SessionPreparationState = pydantic.Field(
default=SessionPreparationState.UNKNOWN
)
state: SessionState = pydantic.Field(default=SessionState.UNKNOWN)
warnings: list[core_models.Message] = pydantic.Field(default=[])
last_seen: str = pydantic.Field(default="UNKNOWN")

Expand Down Expand Up @@ -105,7 +126,9 @@ def resolve_connection_method(self) -> t.Any:
@pydantic.model_validator(mode="after")
def add_warnings_and_last_seen(self) -> t.Any:
self.last_seen = injection.get_last_seen(self.id)
self.state = injection.determine_session_state(self.id)
self.preparation_state, self.state = (
operators.get_operator().get_session_state(self.id)
)

return self

Expand Down
Loading

0 comments on commit d0a71b1

Please sign in to comment.