|
|
@@ -39,7 +39,7 @@ from openhands.runtime.runtime import Runtime
|
|
|
from openhands.runtime.utils.request import (
|
|
|
DEFAULT_RETRY_EXCEPTIONS,
|
|
|
is_404_error,
|
|
|
- send_request,
|
|
|
+ send_request_with_retry,
|
|
|
)
|
|
|
from openhands.runtime.utils.runtime_build import build_runtime_image
|
|
|
from openhands.utils.tenacity_stop import stop_if_should_exit
|
|
|
@@ -97,10 +97,11 @@ class RemoteRuntime(Runtime):
|
|
|
f'Building remote runtime with base image: {self.config.sandbox.base_container_image}'
|
|
|
)
|
|
|
logger.debug(f'RemoteRuntime `{sid}` config:\n{self.config}')
|
|
|
- response = send_request(
|
|
|
+ response = send_request_with_retry(
|
|
|
self.session,
|
|
|
'GET',
|
|
|
f'{self.config.sandbox.remote_runtime_api_url}/registry_prefix',
|
|
|
+ timeout=30,
|
|
|
)
|
|
|
response_json = response.json()
|
|
|
registry_prefix = response_json['registry_prefix']
|
|
|
@@ -125,11 +126,12 @@ class RemoteRuntime(Runtime):
|
|
|
force_rebuild=self.config.sandbox.force_rebuild_runtime,
|
|
|
)
|
|
|
|
|
|
- response = send_request(
|
|
|
+ response = send_request_with_retry(
|
|
|
self.session,
|
|
|
'GET',
|
|
|
f'{self.config.sandbox.remote_runtime_api_url}/image_exists',
|
|
|
params={'image': self.container_image},
|
|
|
+ timeout=30,
|
|
|
)
|
|
|
if response.status_code != 200 or not response.json()['exists']:
|
|
|
raise RuntimeError(
|
|
|
@@ -164,11 +166,12 @@ class RemoteRuntime(Runtime):
|
|
|
|
|
|
self.send_status_message('STATUS$WAITING_FOR_CLIENT')
|
|
|
# Start the sandbox using the /start endpoint
|
|
|
- response = send_request(
|
|
|
+ response = send_request_with_retry(
|
|
|
self.session,
|
|
|
'POST',
|
|
|
f'{self.config.sandbox.remote_runtime_api_url}/start',
|
|
|
json=start_request,
|
|
|
+ timeout=300,
|
|
|
)
|
|
|
if response.status_code != 201:
|
|
|
raise RuntimeError(f'Failed to start sandbox: {response.text}')
|
|
|
@@ -216,7 +219,7 @@ class RemoteRuntime(Runtime):
|
|
|
)
|
|
|
def _wait_until_alive(self):
|
|
|
logger.info(f'Waiting for runtime to be alive at url: {self.runtime_url}')
|
|
|
- response = send_request(
|
|
|
+ response = send_request_with_retry(
|
|
|
self.session,
|
|
|
'GET',
|
|
|
f'{self.runtime_url}/alive',
|
|
|
@@ -235,7 +238,7 @@ class RemoteRuntime(Runtime):
|
|
|
def close(self, timeout: int = 10):
|
|
|
if self.runtime_id:
|
|
|
try:
|
|
|
- response = send_request(
|
|
|
+ response = send_request_with_retry(
|
|
|
self.session,
|
|
|
'POST',
|
|
|
f'{self.config.sandbox.remote_runtime_api_url}/stop',
|
|
|
@@ -273,7 +276,7 @@ class RemoteRuntime(Runtime):
|
|
|
logger.info('Executing action')
|
|
|
request_body = {'action': event_to_dict(action)}
|
|
|
logger.debug(f'Request body: {request_body}')
|
|
|
- response = send_request(
|
|
|
+ response = send_request_with_retry(
|
|
|
self.session,
|
|
|
'POST',
|
|
|
f'{self.runtime_url}/execute_action',
|
|
|
@@ -351,7 +354,7 @@ class RemoteRuntime(Runtime):
|
|
|
|
|
|
params = {'destination': sandbox_dest, 'recursive': str(recursive).lower()}
|
|
|
|
|
|
- response = send_request(
|
|
|
+ response = send_request_with_retry(
|
|
|
self.session,
|
|
|
'POST',
|
|
|
f'{self.runtime_url}/upload_file',
|
|
|
@@ -360,6 +363,7 @@ class RemoteRuntime(Runtime):
|
|
|
retry_exceptions=list(
|
|
|
filter(lambda e: e != TimeoutError, DEFAULT_RETRY_EXCEPTIONS)
|
|
|
),
|
|
|
+ timeout=300,
|
|
|
)
|
|
|
if response.status_code == 200:
|
|
|
logger.info(
|
|
|
@@ -385,7 +389,7 @@ class RemoteRuntime(Runtime):
|
|
|
if path is not None:
|
|
|
data['path'] = path
|
|
|
|
|
|
- response = send_request(
|
|
|
+ response = send_request_with_retry(
|
|
|
self.session,
|
|
|
'POST',
|
|
|
f'{self.runtime_url}/list_files',
|
|
|
@@ -393,6 +397,7 @@ class RemoteRuntime(Runtime):
|
|
|
retry_exceptions=list(
|
|
|
filter(lambda e: e != TimeoutError, DEFAULT_RETRY_EXCEPTIONS)
|
|
|
),
|
|
|
+ timeout=30, # The runtime sbould already be running here
|
|
|
)
|
|
|
if response.status_code == 200:
|
|
|
response_json = response.json()
|