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

Add response headers logging for dRPC #211

Merged
merged 2 commits into from
Apr 26, 2024
Merged
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
42 changes: 33 additions & 9 deletions eth_defi/event_reader/fast_json_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@

import logging
from json import JSONDecodeError
from typing import cast
from typing import Any, cast

import ujson
from web3 import Web3
from web3._utils.request import get_response_from_post_request
from web3.providers import JSONBaseProvider
from web3.types import RPCResponse
from web3.providers.rpc import HTTPProvider
from web3.types import RPCEndpoint, RPCResponse

logger = logging.getLogger(__name__)

Expand All @@ -20,7 +22,7 @@ class PartialHttpResponseException(JSONDecodeError):


def _fast_decode_rpc_response(raw_response: bytes) -> RPCResponse:
"""Uses ujson for speeded up JSON decoding instead of web3.py default JSON."""
"""Uses ujson for speeding up JSON decoding instead of web3.py default JSON."""
try:
decoded = ujson.loads(raw_response)
except ValueError as e:
Expand All @@ -31,17 +33,39 @@ def _fast_decode_rpc_response(raw_response: bytes) -> RPCResponse:
return cast(RPCResponse, decoded)


def patch_provider(provider: JSONBaseProvider):
"""Monkey-patch web3.py provider for faster JSON decoding.
def _make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse:
"""Add response headers logging in case of exception raised."""

This greatly improves JSON-RPC API access speeds, when fetching
multiple and large responses.
"""
request_data = self.encode_rpc_request(method, params)
raw_response = get_response_from_post_request(
self.endpoint_uri,
data=request_data,
**self.get_request_kwargs(),
)
raw_response.raise_for_status()

try:
return _fast_decode_rpc_response(raw_response.content)
except Exception as e:
logger.error(
"Unexpected decode RPC response error: %s, current provider ID is %s",
str(e),
raw_response.headers.get("x-drpc-trace-id", ""),
extra={"response_headers": raw_response.headers},
)
logger.exception(e)
raise


def patch_provider(provider: JSONBaseProvider):
"""Monkey-patch web3.py provider for faster JSON decoding and additional logging."""
if isinstance(provider, HTTPProvider):
provider.make_request = _make_request.__get__(provider)
provider.decode_rpc_response = _fast_decode_rpc_response


def patch_web3(web3: Web3):
"""Monkey-patch web3.py provider for faster JSON decoding.
"""Monkey-patch web3.py provider for faster JSON decoding and additional logging.

This greatly improves JSON-RPC API access speeds, when fetching
multiple and large responses.
Expand Down
Loading