-
Notifications
You must be signed in to change notification settings - Fork 1
server: fix client/protocol init, customize server config, consolidate health manager #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
cbf207d
to
bea4408
Compare
add health manager to server, unify state fix control handler missing consolidate HealthManager with StreamState, extend server
bea4408
to
fd6567f
Compare
fd6567f
to
598f8ef
Compare
@@ -48,7 +47,6 @@ | |||
"AudioOutput", | |||
"TricklePublisher", | |||
"TrickleSubscriber", | |||
"StreamHealthManager", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Random nit: mind fixing the tab vs spaces issue on line 42 referring to "StreamProcessor"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in adf2494
pytrickle/server.py
Outdated
@@ -102,8 +298,9 @@ async def _handle_start_stream(self, request: web.Request) -> web.Response: | |||
height = params_dict.get("height", 512) | |||
max_framerate = params_dict.get("max_framerate", None) # None will use default | |||
|
|||
# Create protocol and client (align with current Client/Protocol API) | |||
protocol = TrickleProtocol( | |||
#TODO: Consider adding lifecycle_lock here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is worth adding async with self._lifecycle_lock:
here or however you envisioned it to prevent race conditions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in aaea932, tested stop/start successfully
if self.subscribe_queue is not None: | ||
self.subscribe_queue.put(None) | ||
except Exception: | ||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should log the exceptions here and on 211
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added logging in adf2494
pytrickle/publisher.py
Outdated
pass | ||
finally: | ||
self.session = None | ||
connector = aiohttp.TCPConnector(verify_ssl=False, limit=0, keepalive_timeout=5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keepalive and client timeout should be configurable or at least constants applied to class params.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've now made the timeouts configurable all the way through TrickleServer
and TrickleClient
. See 685e12f
When initializing StreamServer
, user can provide subscriber_timeout
and/or publisher_timeout
to configure these. I removed the keep alive mechanism as it's not necessary for these short connections.
I also updated TrickleSubscriber
to follow similar constant patterns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second thought - some publishers may need keep-alive packets. Considering the case of no data sent for 30+ seconds on a running stream. I'll add keep-alive pings back in for publishers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keep-alive added back 0941d21. It is only configurable by Publisher currently and defaults to a class constant
pytrickle/publisher.py
Outdated
# If preconnect failed due to connection reuse issues, retry once immediately | ||
if self.next_writer is None and not self._should_stop(): | ||
logger.info("Preconnect returned None, retrying once immediately") | ||
await asyncio.sleep(0.05) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also should be a constant ( RETRY_DELAY_SECONDS? )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to use constants in 685e12f
try: | ||
await self.session.close() | ||
except Exception: | ||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log exception
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added logging in adf2494
connector = aiohttp.TCPConnector(verify_ssl=False) | ||
timeout = aiohttp.ClientTimeout(total=30) # Reduced timeout for faster shutdown | ||
self.session = aiohttp.ClientSession(connector=connector, timeout=timeout) | ||
# Always create a fresh session on start to avoid stale keep-alives across streams |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you elaborate a bit more on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is related to a change to close any open connection sessions when starting the publisher. It protects against memory issues if start()
is called when the publisher is already running.
The previous start()
would create a new connection without checking this. It is also somewhat relevant to the discussion above on timeout and keep_alive messages #13 (comment)
pytrickle/state.py
Outdated
Example: | ||
set_state(PipelineState.READY) | ||
""" | ||
if state == PipelineState.WARMING_PIPELINE: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could be refactored for maintainability and readability. Consider creating a mapping of state transitions and a helper referring to the map. sending you a DM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consolidated state transition logic and removed unused code f3f7459
1191a82
to
f1b72a0
Compare
This pull request introduces several improvements and refactorings to the PyTrickle streaming library, focusing on stream state management, reliability, and documentation clarity. The most significant change is the replacement of the
StreamHealthManager
with a more genericStreamState
, leading to updates across the stream management logic. Additional enhancements include improved publisher error recovery, better handling of protocol shutdown, and clearer documentation of stream management approaches.Stream State Management Refactor:
StreamHealthManager
withStreamState
throughout the stream manager classes, updating all references and logic to use the new state management interface. This simplifies and standardizes how stream health and lifecycle are tracked and reported. (pytrickle/manager.py
,pytrickle/__init__.py
,pytrickle/server.py
,pytrickle/health.py
removed) [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12]Publisher and Protocol Reliability Improvements:
next()
method to allow recovery from transient errors and retry preconnects, enhancing robustness in the face of network or encoder issues. (pytrickle/publisher.py
)pytrickle/protocol.py
) [1] [2]pytrickle/publisher.py
)Documentation and API Clarity:
README.md
to clarify the different stream management approaches available in PyTrickle, helping users select the right architecture for their needs.Frame Utilities:
FrameFactory
class to provide helper methods for constructing video and audio frames with consistent defaults. (pytrickle/frames.py
)Server Extensibility:
RouteConfig
dataclass for configuring custom routes in the server, laying groundwork for more flexible HTTP API extensions. (pytrickle/server.py
)Let me know if you need a deeper dive into any of these changes!