|
22 | 22 | logger = logging.getLogger(__name__)
|
23 | 23 |
|
24 | 24 |
|
| 25 | +DEFAULT_ATTACH_FIRST_RESP_TIMEOUT = 600 |
| 26 | +DEFAULT_ATTACH_LONG_TIMEOUT = 31536000 # year |
| 27 | + |
| 28 | + |
25 | 29 | class QuerySessionStateEnum(enum.Enum):
|
26 | 30 | NOT_INITIALIZED = "NOT_INITIALIZED"
|
27 | 31 | CREATED = "CREATED"
|
@@ -136,6 +140,12 @@ def __init__(self, driver: common_utils.SupportedDriverType, settings: Optional[
|
136 | 140 | self._driver = driver
|
137 | 141 | self._settings = self._get_client_settings(driver, settings)
|
138 | 142 | self._state = QuerySessionState(settings)
|
| 143 | + self._attach_settings: BaseRequestSettings = ( |
| 144 | + BaseRequestSettings() |
| 145 | + .with_operation_timeout(DEFAULT_ATTACH_LONG_TIMEOUT) |
| 146 | + .with_cancel_after(DEFAULT_ATTACH_LONG_TIMEOUT) |
| 147 | + .with_timeout(DEFAULT_ATTACH_LONG_TIMEOUT) |
| 148 | + ) |
139 | 149 |
|
140 | 150 | def _get_client_settings(
|
141 | 151 | self,
|
@@ -168,12 +178,12 @@ def _delete_call(self, settings: Optional[BaseRequestSettings] = None) -> "BaseQ
|
168 | 178 | settings=settings,
|
169 | 179 | )
|
170 | 180 |
|
171 |
| - def _attach_call(self, settings: Optional[BaseRequestSettings] = None) -> Iterable[_apis.ydb_query.SessionState]: |
| 181 | + def _attach_call(self) -> Iterable[_apis.ydb_query.SessionState]: |
172 | 182 | return self._driver(
|
173 | 183 | _apis.ydb_query.AttachSessionRequest(session_id=self._state.session_id),
|
174 | 184 | _apis.QueryService.Stub,
|
175 | 185 | _apis.QueryService.AttachSession,
|
176 |
| - settings=settings, |
| 186 | + settings=self._attach_settings, |
177 | 187 | )
|
178 | 188 |
|
179 | 189 | def _execute_call(
|
@@ -213,24 +223,32 @@ class QuerySession(BaseQuerySession):
|
213 | 223 |
|
214 | 224 | _stream = None
|
215 | 225 |
|
216 |
| - def _attach(self, settings: Optional[BaseRequestSettings] = None) -> None: |
217 |
| - self._stream = self._attach_call(settings=settings) |
| 226 | + def _attach(self, first_resp_timeout: int = DEFAULT_ATTACH_FIRST_RESP_TIMEOUT) -> None: |
| 227 | + self._stream = self._attach_call() |
218 | 228 | status_stream = _utilities.SyncResponseIterator(
|
219 | 229 | self._stream,
|
220 | 230 | lambda response: common_utils.ServerStatus.from_proto(response),
|
221 | 231 | )
|
222 | 232 |
|
223 |
| - first_response = next(status_stream) |
224 |
| - if first_response.status != issues.StatusCode.SUCCESS: |
225 |
| - pass |
| 233 | + try: |
| 234 | + first_response = _utilities.get_first_message_with_timeout( |
| 235 | + status_stream, |
| 236 | + first_resp_timeout, |
| 237 | + ) |
| 238 | + if first_response.status != issues.StatusCode.SUCCESS: |
| 239 | + raise RuntimeError("Failed to attach session") |
| 240 | + except Exception as e: |
| 241 | + self._state.reset() |
| 242 | + status_stream.cancel() |
| 243 | + raise e |
226 | 244 |
|
227 | 245 | self._state.set_attached(True)
|
228 | 246 | self._state._change_state(QuerySessionStateEnum.CREATED)
|
229 | 247 |
|
230 | 248 | threading.Thread(
|
231 | 249 | target=self._check_session_status_loop,
|
232 | 250 | args=(status_stream,),
|
233 |
| - name="check session status thread", |
| 251 | + name="attach stream thread", |
234 | 252 | daemon=True,
|
235 | 253 | ).start()
|
236 | 254 |
|
|
0 commit comments