Skip to content

Commit 97258fb

Browse files
authored
Merge pull request #43 from chainstacklabs/dev
Exclude connection time (TCP/TLS overhead)
2 parents 1293993 + 39c1baf commit 97258fb

File tree

2 files changed

+61
-9
lines changed

2 files changed

+61
-9
lines changed

common/metric_types.py

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -172,34 +172,85 @@ def get_params_from_state(state_data: dict[str, Any]) -> dict[str, Any]:
172172
return {}
173173

174174
async def fetch_data(self) -> float:
175-
"""Measure single request latency with a retry on 429 error."""
175+
"""Measure single request latency with detailed timing."""
176176
endpoint: str | None = self.config.endpoints.get_endpoint()
177177

178+
# Add trace config for detailed timing
179+
trace_config = aiohttp.TraceConfig()
180+
timing = {}
181+
182+
async def on_request_start(session, context, params):
183+
timing["start"] = time.monotonic()
184+
185+
async def on_dns_resolvehost_start(session, context, params):
186+
timing["dns_start"] = time.monotonic()
187+
188+
async def on_dns_resolvehost_end(session, context, params):
189+
timing["dns_end"] = time.monotonic()
190+
191+
async def on_connection_create_start(session, context, params):
192+
timing["conn_start"] = time.monotonic()
193+
194+
async def on_connection_create_end(session, context, params):
195+
timing["conn_end"] = time.monotonic()
196+
197+
async def on_request_end(session, context, params):
198+
timing["end"] = time.monotonic()
199+
200+
trace_config.on_request_start.append(on_request_start)
201+
trace_config.on_dns_resolvehost_start.append(on_dns_resolvehost_start)
202+
trace_config.on_dns_resolvehost_end.append(on_dns_resolvehost_end)
203+
trace_config.on_connection_create_start.append(on_connection_create_start)
204+
trace_config.on_connection_create_end.append(on_connection_create_end)
205+
trace_config.on_request_end.append(on_request_end)
206+
178207
async with aiohttp.ClientSession(
179-
timeout=aiohttp.ClientTimeout(total=self.config.timeout)
208+
timeout=aiohttp.ClientTimeout(total=self.config.timeout),
209+
trace_configs=[trace_config],
180210
) as session:
181-
response_time = 0.0 # Do not include retried requests after 429 error
182-
response = None # type: ignore
211+
response_time = 0.0
212+
response = None
183213

184214
for retry_count in range(MAX_RETRIES):
185215
start_time: float = time.monotonic()
186-
response: aiohttp.ClientResponse = await self._send_request(session, endpoint) # type: ignore
216+
response: aiohttp.ClientResponse = await self._send_request(
217+
session, endpoint
218+
)
187219
response_time: float = time.monotonic() - start_time
188220

189221
if response.status == 429 and retry_count < MAX_RETRIES - 1:
190222
wait_time = int(response.headers.get("Retry-After", 15))
191-
await response.release() # Release before retry
223+
await response.release()
192224
await asyncio.sleep(wait_time)
193225
continue
194226

195227
break
196228

229+
# Log timing breakdown
230+
if "dns_start" in timing and "dns_end" in timing:
231+
dns_time = (timing["dns_end"] - timing["dns_start"]) * 1000
232+
else:
233+
dns_time = 0
234+
235+
if "conn_start" in timing and "conn_end" in timing:
236+
conn_time = (timing["conn_end"] - timing["conn_start"]) * 1000
237+
else:
238+
conn_time = 0
239+
240+
total_time = response_time * 1000
241+
242+
# Log breakdown
243+
provider = self.labels.get_label(MetricLabelKey.PROVIDER)
244+
method = self.labels.get_label(MetricLabelKey.API_METHOD)
245+
print(
246+
f"[{provider}] {method} timing: DNS={dns_time:.0f}ms, Connect={conn_time:.0f}ms, Total={total_time:.0f}ms, Endpoint={endpoint}"
247+
)
248+
197249
if not response:
198250
raise ValueError("No response received")
199251

200252
try:
201253
if response.status != 200:
202-
# Let the error propagate with status code
203254
raise aiohttp.ClientResponseError(
204255
request_info=response.request_info,
205256
history=(),
@@ -212,7 +263,8 @@ async def fetch_data(self) -> float:
212263
if "error" in json_response:
213264
raise ValueError(f"JSON-RPC error: {json_response['error']}")
214265

215-
return response_time
266+
# Return RPC time only (exclude connection time)
267+
return response_time - (conn_time / 1000)
216268
finally:
217269
await response.release()
218270

tests/test_api_read.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def main() -> None:
2929
setup_environment()
3030

3131
# Import handler after environment setup
32-
from api.read.bnbsc import handler
32+
from api.read.ethereum import handler
3333

3434
server = HTTPServer(("localhost", 8000), handler)
3535
print("Server started at http://localhost:8000")

0 commit comments

Comments
 (0)