Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pytrickle/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,7 @@ def is_healthy(self) -> bool:
def get_health_summary(self) -> str:
"""Get a simple health status string."""
state = self.state.get_pipeline_state()
return state.get('state', 'unknown')
return state.get('status', 'unknown')

async def run_forever(self):
"""Run the server forever."""
Expand Down
24 changes: 19 additions & 5 deletions pytrickle/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ def pipeline_ready(self) -> bool:
def set_active_client(self, active: bool):
"""Track whether there's an active streaming client."""
self.active_client = active

# Transition internal state based on activity (only if not in ERROR state)
if not self.error_event.is_set():
if self.active_streams > 0 or self.active_client:
if self._state != PipelineState.OK:
self.set_state(PipelineState.OK)
elif self.startup_complete and self.pipeline_ready:
if self._state != PipelineState.IDLE:
self.set_state(PipelineState.IDLE)

def update_component_health(self, component_name: str, health_data: dict):
"""Update component health and log errors without persisting them.
Expand Down Expand Up @@ -154,6 +163,15 @@ def set_startup_complete(self) -> None:
def update_active_streams(self, count: int) -> None:
"""Update number of active streams for health/status reporting."""
self.active_streams = max(0, int(count))

# Transition internal state based on activity (only if not in ERROR state)
if not self.error_event.is_set():
if self.active_streams > 0 or self.active_client:
if self._state != PipelineState.OK:
self.set_state(PipelineState.OK)
elif self.startup_complete and self.pipeline_ready:
if self._state != PipelineState.IDLE:
self.set_state(PipelineState.IDLE)

def is_error(self) -> bool:
return self.error_event.is_set()
Expand Down Expand Up @@ -199,12 +217,8 @@ def get_pipeline_state(self) -> dict:
status = "LOADING"

return {
"status": status, # Primary health status
"state": status, # Backward compatibility
"error_message": None, # Keep compatibility with previous health payload
"status": status,
"pipeline_ready": self.pipeline_ready,
"active_streams": self.active_streams,
"startup_complete": self.startup_complete,
"pipeline_state": self._state.name, # Internal state name for debugging
"additional_info": {},
}
2 changes: 1 addition & 1 deletion tests/test_state_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test_state_transitions(self):
state.update_active_streams(1)
state.set_active_client(True)
data = state.get_state()
assert state.state == PipelineState.IDLE # Internal state doesn't auto-transition
assert state.state == PipelineState.OK # Internal state auto-transitions to OK after stream starts
assert data["status"] == "OK" # But status reflects activity

# When streams stop → status becomes IDLE
Expand Down