Skip to content

Commit

Permalink
add rate limit and faster default speed
Browse files Browse the repository at this point in the history
  • Loading branch information
wakamex committed Oct 28, 2022
1 parent ceb358d commit 61ab88d
Showing 1 changed file with 42 additions and 20 deletions.
62 changes: 42 additions & 20 deletions ape_alchemy/provider.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import os, time
import numpy.random as random
from typing import Any, Dict, Iterator

from ape.api import UpstreamProvider, Web3Provider
Expand Down Expand Up @@ -26,6 +27,12 @@ class Alchemy(Web3Provider, UpstreamProvider):

network_uris: Dict[tuple, str] = {}

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.block_page_size = 5000
self.concurrency = 1
print(f"setting block_page_size to {self.block_page_size} and concurrency to {self.concurrency}")

@property
def uri(self):
"""
Expand Down Expand Up @@ -129,22 +136,37 @@ def get_virtual_machine_error(self, exception: Exception) -> VirtualMachineError
return VirtualMachineError(message=message)

def _make_request(self, endpoint: str, parameters: list) -> Any:
try:
return super()._make_request(endpoint, parameters)
except HTTPError as err:
response_data = err.response.json()
if "error" not in response_data:
raise AlchemyProviderError(str(err)) from err

error_data = response_data["error"]
message = (
error_data.get("message", str(error_data))
if isinstance(error_data, dict)
else error_data
)
cls = (
AlchemyFeatureNotAvailable
if "is not available" in message
else AlchemyProviderError
)
raise cls(message) from err
MIN_RETRY_DELAY = 1000
RETRY_BACKOFF_FACTOR = 2
MAX_RETRY_DELAY = 30000
MAX_RETRIES = 3
# RETRY_INTERVAL = 1000
RETRY_JITTER = 250
for i in range(0,MAX_RETRIES):
print(f"_make_request attempt {i}")
try:
return super()._make_request(endpoint, parameters)
except HTTPError as err:
response_data = err.response.json()
if "error" not in response_data:
raise AlchemyProviderError(str(err)) from err

error_data = response_data["error"]
message = (
error_data.get("message", str(error_data))
if isinstance(error_data, dict)
else error_data
)
if message.__contains__("exceeded its compute units"):
RETRY_INTERVAL = min(MAX_RETRY_DELAY, MIN_RETRY_DELAY * RETRY_BACKOFF_FACTOR ** i)
print(f"Alchemy compute units exceeded, retrying #{i} in {RETRY_INTERVAL} ms")
delay = RETRY_INTERVAL + random.randint(0, RETRY_JITTER)
time.sleep(delay / 1000)
continue
cls = (
AlchemyFeatureNotAvailable
if "is not available" in message
else AlchemyProviderError
)
raise cls(message) from err
raise AlchemyProviderError(f"Rate limited for ${MAX_RETRIES} consecutive attempts.")

0 comments on commit 61ab88d

Please sign in to comment.