Skip to content
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

[RFC] Implement "related events" API. #238

Closed
wants to merge 2 commits into from
Closed
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
11 changes: 10 additions & 1 deletion h2/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -1296,7 +1296,16 @@ def receive_data(self, data):

try:
for frame in self.incoming_buffer:
events.extend(self._receive_frame(frame))
frame_events = self._receive_frame(frame)

# If more than one event popped out here, we want to process
# them as "related events".
if len(frame_events) > 1:
event_set = frozenset(frame_events)
for event in frame_events:
event.related_events = event_set

events.extend(frame_events)
except InvalidPaddingError:
self._terminate_connection(PROTOCOL_ERROR)
raise ProtocolError("Received frame with invalid padding.")
Expand Down
70 changes: 70 additions & 0 deletions h2/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ class RequestReceived(object):
.. versionchanged:: 2.3.0
Changed the type of ``headers`` to :class:`HeaderTuple
<hpack:hpack.HeaderTuple>`. This has no effect on current users.

.. versionchanged:: 2.4.0
Added ``related_events`` property.
"""
def __init__(self):
#: The Stream ID for the stream this request was made on.
Expand All @@ -31,6 +34,13 @@ def __init__(self):
#: The request headers.
self.headers = None

#: Any events "related" to this one: that is, any events that occurred
#: at the exact same time as this one because their data was carried on
#: the same frame. All of these events need to be processed at once.
#:
#: .. versionadded:: 2.4.0
self.related_events = frozenset()

def __repr__(self):
return "<RequestReceived stream_id:%s, headers:%s>" % (
self.stream_id, self.headers
Expand All @@ -46,6 +56,9 @@ class ResponseReceived(object):
.. versionchanged:: 2.3.0
Changed the type of ``headers`` to :class:`HeaderTuple
<hpack:hpack.HeaderTuple>`. This has no effect on current users.

.. versionchanged:: 2.4.0
Added ``related_events`` property.
"""
def __init__(self):
#: The Stream ID for the stream this response was made on.
Expand All @@ -54,6 +67,13 @@ def __init__(self):
#: The response headers.
self.headers = None

#: Any events "related" to this one: that is, any events that occurred
#: at the exact same time as this one because their data was carried on
#: the same frame. All of these events need to be processed at once.
#:
#: .. versionadded:: 2.4.0
self.related_events = frozenset()

def __repr__(self):
return "<ResponseReceived stream_id:%s, headers:%s>" % (
self.stream_id, self.headers
Expand All @@ -72,6 +92,9 @@ class TrailersReceived(object):
.. versionchanged:: 2.3.0
Changed the type of ``headers`` to :class:`HeaderTuple
<hpack:hpack.HeaderTuple>`. This has no effect on current users.

.. versionchanged:: 2.4.0
Added ``related_events`` property.
"""
def __init__(self):
#: The Stream ID for the stream on which these trailers were received.
Expand All @@ -80,6 +103,13 @@ def __init__(self):
#: The trailers themselves.
self.headers = None

#: Any events "related" to this one: that is, any events that occurred
#: at the exact same time as this one because their data was carried on
#: the same frame. All of these events need to be processed at once.
#:
#: .. versionadded:: 2.4.0
self.related_events = frozenset()

def __repr__(self):
return "<TrailersReceived stream_id:%s, headers:%s>" % (
self.stream_id, self.headers
Expand All @@ -104,6 +134,9 @@ class InformationalResponseReceived(object):
.. versionchanged:: 2.3.0
Changed the type of ``headers`` to :class:`HeaderTuple
<hpack:hpack.HeaderTuple>`. This has no effect on current users.

.. versionchanged:: 2.4.0
Added ``related_events`` property.
"""
def __init__(self):
#: The Stream ID for the stream this informational response was made
Expand All @@ -113,6 +146,13 @@ def __init__(self):
#: The headers for this informational response.
self.headers = None

#: Any events "related" to this one: that is, any events that occurred
#: at the exact same time as this one because their data was carried on
#: the same frame. All of these events need to be processed at once.
#:
#: .. versionadded:: 2.4.0
self.related_events = frozenset()

def __repr__(self):
return "<InformationalResponseReceived stream_id:%s, headers:%s>" % (
self.stream_id, self.headers
Expand All @@ -124,6 +164,9 @@ class DataReceived(object):
The DataReceived event is fired whenever data is received on a stream from
the remote peer. The event carries the data itself, and the stream ID on
which the data was received.

.. versionchanged:: 2.4.0
Added ``related_events`` property.
"""
def __init__(self):
#: The Stream ID for the stream this data was received on.
Expand All @@ -138,6 +181,13 @@ def __init__(self):
#: than ``len(data)``.
self.flow_controlled_length = None

#: Any events "related" to this one: that is, any events that occurred
#: at the exact same time as this one because their data was carried on
#: the same frame. All of these events need to be processed at once.
#:
#: .. versionadded:: 2.4.0
self.related_events = frozenset()

def __repr__(self):
return (
"<DataReceived stream_id:%s, "
Expand Down Expand Up @@ -243,11 +293,21 @@ class StreamEnded(object):
The StreamEnded event is fired whenever a stream is ended by a remote
party. The stream may not be fully closed if it has not been closed
locally, but no further data or headers should be expected on that stream.

.. versionchanged:: 2.4.0
Added ``related_events`` property.
"""
def __init__(self):
#: The Stream ID of the stream that was closed.
self.stream_id = None

#: Any events "related" to this one: that is, any events that occurred
#: at the exact same time as this one because their data was carried on
#: the same frame. All of these events need to be processed at once.
#:
#: .. versionadded:: 2.4.0
self.related_events = frozenset()

def __repr__(self):
return "<StreamEnded stream_id:%s>" % self.stream_id

Expand Down Expand Up @@ -333,6 +393,9 @@ class PriorityUpdated(object):
This event is purely advisory, and does not need to be acted on.

.. versionadded:: 2.0.0

.. versionchanged:: 2.4.0
Added ``related_events`` property.
"""
def __init__(self):
#: The ID of the stream whose priority information is being updated.
Expand All @@ -350,6 +413,13 @@ def __init__(self):
#: parent.
self.exclusive = None

#: Any events "related" to this one: that is, any events that occurred
#: at the exact same time as this one because their data was carried on
#: the same frame. All of these events need to be processed at once.
#:
#: .. versionadded:: 2.4.0
self.related_events = frozenset()

def __repr__(self):
return (
"<PriorityUpdated stream_id:%s, weight:%s, depends_on:%s, "
Expand Down
Loading