langfun 0.1.2.dev202509300805__py3-none-any.whl → 0.1.2.dev202510020804__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of langfun might be problematic. Click here for more details.
- langfun/core/llms/gemini.py +5 -0
- langfun/core/llms/rest.py +4 -0
- langfun/env/base_environment.py +81 -47
- langfun/env/base_feature.py +3 -2
- langfun/env/base_sandbox.py +3 -3
- langfun/env/base_test.py +6 -1
- langfun/env/event_handlers/base.py +75 -9
- langfun/env/event_handlers/event_logger.py +30 -8
- langfun/env/event_handlers/event_logger_test.py +7 -0
- langfun/env/event_handlers/metric_writer.py +111 -49
- langfun/env/event_handlers/metric_writer_test.py +36 -26
- langfun/env/test_utils.py +6 -3
- {langfun-0.1.2.dev202509300805.dist-info → langfun-0.1.2.dev202510020804.dist-info}/METADATA +1 -1
- {langfun-0.1.2.dev202509300805.dist-info → langfun-0.1.2.dev202510020804.dist-info}/RECORD +17 -17
- {langfun-0.1.2.dev202509300805.dist-info → langfun-0.1.2.dev202510020804.dist-info}/WHEEL +0 -0
- {langfun-0.1.2.dev202509300805.dist-info → langfun-0.1.2.dev202510020804.dist-info}/licenses/LICENSE +0 -0
- {langfun-0.1.2.dev202509300805.dist-info → langfun-0.1.2.dev202510020804.dist-info}/top_level.txt +0 -0
langfun/core/llms/gemini.py
CHANGED
|
@@ -752,6 +752,11 @@ class Gemini(rest.REST):
|
|
|
752
752
|
prompt.as_format('gemini', chunk_preprocessor=modality_conversion)
|
|
753
753
|
)
|
|
754
754
|
request['contents'] = contents
|
|
755
|
+
# Users could use `metadata_gemini_tools` to pass Gemini tools. For example,
|
|
756
|
+
# for enabling Search Grounding, users could pass:
|
|
757
|
+
# metadata_gemini_tools=[{'google_search': {}}]
|
|
758
|
+
if tools := prompt.metadata.get('gemini_tools'):
|
|
759
|
+
request['tools'] = tools
|
|
755
760
|
return request
|
|
756
761
|
|
|
757
762
|
def _generation_config(
|
langfun/core/llms/rest.py
CHANGED
|
@@ -98,7 +98,9 @@ class REST(lf.LanguageModel):
|
|
|
98
98
|
raise lf.TemporaryLMError(str(e)) from e
|
|
99
99
|
except (
|
|
100
100
|
requests.exceptions.ConnectionError,
|
|
101
|
+
requests.exceptions.ChunkedEncodingError,
|
|
101
102
|
ConnectionError,
|
|
103
|
+
ConnectionResetError,
|
|
102
104
|
) as e:
|
|
103
105
|
error_message = str(e)
|
|
104
106
|
if 'REJECTED_CLIENT_THROTTLED' in error_message:
|
|
@@ -107,6 +109,8 @@ class REST(lf.LanguageModel):
|
|
|
107
109
|
raise lf.TemporaryLMError(error_message) from e
|
|
108
110
|
if 'UNREACHABLE_ERROR' in error_message:
|
|
109
111
|
raise lf.TemporaryLMError(error_message) from e
|
|
112
|
+
if 'Connection reset by peer' in error_message:
|
|
113
|
+
raise lf.TemporaryLMError(error_message) from e
|
|
110
114
|
raise lf.LMError(error_message) from e
|
|
111
115
|
|
|
112
116
|
def _error(self, status_code: int, content: str) -> lf.LMError:
|
langfun/env/base_environment.py
CHANGED
|
@@ -359,6 +359,7 @@ class BaseEnvironment(interface.Environment):
|
|
|
359
359
|
return
|
|
360
360
|
|
|
361
361
|
self._set_status(self.Status.SHUTTING_DOWN)
|
|
362
|
+
self.on_shutting_down()
|
|
362
363
|
|
|
363
364
|
shutting_down_time = time.time()
|
|
364
365
|
try:
|
|
@@ -419,7 +420,6 @@ class BaseEnvironment(interface.Environment):
|
|
|
419
420
|
)
|
|
420
421
|
# Append is atomic and does not require locking.
|
|
421
422
|
self._sandbox_pool.append(sandbox)
|
|
422
|
-
self._offline_start_time = None
|
|
423
423
|
return sandbox
|
|
424
424
|
except (
|
|
425
425
|
interface.EnvironmentError, interface.SandboxStateError
|
|
@@ -432,18 +432,28 @@ class BaseEnvironment(interface.Environment):
|
|
|
432
432
|
set_acquired: bool = False,
|
|
433
433
|
) -> base_sandbox.BaseSandbox:
|
|
434
434
|
"""Brings up a new sandbox."""
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
sandbox.
|
|
446
|
-
|
|
435
|
+
env_error = None
|
|
436
|
+
try:
|
|
437
|
+
sandbox = self._create_sandbox(
|
|
438
|
+
sandbox_id=sandbox_id,
|
|
439
|
+
reusable=self.enable_pooling,
|
|
440
|
+
proactive_session_setup=self.proactive_session_setup,
|
|
441
|
+
keepalive_interval=self.sandbox_keepalive_interval,
|
|
442
|
+
)
|
|
443
|
+
for handler in self.event_handlers:
|
|
444
|
+
sandbox.add_event_handler(handler)
|
|
445
|
+
sandbox.start()
|
|
446
|
+
if set_acquired:
|
|
447
|
+
sandbox.set_acquired()
|
|
448
|
+
return sandbox
|
|
449
|
+
except (interface.EnvironmentError, interface.SandboxStateError) as e:
|
|
450
|
+
env_error = e
|
|
451
|
+
raise e
|
|
452
|
+
finally:
|
|
453
|
+
if env_error is None:
|
|
454
|
+
self._offline_start_time = None
|
|
455
|
+
elif self._offline_start_time is None:
|
|
456
|
+
self._offline_start_time = time.time()
|
|
447
457
|
|
|
448
458
|
def _bring_up_sandbox_with_retry(
|
|
449
459
|
self,
|
|
@@ -486,8 +496,6 @@ class BaseEnvironment(interface.Environment):
|
|
|
486
496
|
shutdown_env_upon_outage: bool = True
|
|
487
497
|
):
|
|
488
498
|
"""Raises error if the grace period has passed or wait for retry."""
|
|
489
|
-
if self._offline_start_time is None:
|
|
490
|
-
self._offline_start_time = time.time()
|
|
491
499
|
if self.offline_duration > self.outage_grace_period:
|
|
492
500
|
if shutdown_env_upon_outage:
|
|
493
501
|
self.shutdown()
|
|
@@ -505,39 +513,47 @@ class BaseEnvironment(interface.Environment):
|
|
|
505
513
|
"""Housekeeping loop for the environment."""
|
|
506
514
|
while self._status not in (self.Status.SHUTTING_DOWN, self.Status.OFFLINE):
|
|
507
515
|
housekeep_start_time = time.time()
|
|
516
|
+
|
|
517
|
+
is_online = True
|
|
508
518
|
dead_pool_indices = [
|
|
509
519
|
i for i, s in enumerate(self._sandbox_pool)
|
|
510
520
|
if s.status == interface.Sandbox.Status.OFFLINE
|
|
511
521
|
]
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
522
|
+
replaced_indices = []
|
|
523
|
+
|
|
524
|
+
if dead_pool_indices:
|
|
525
|
+
replaced_indices = self._replace_dead_sandboxes(dead_pool_indices)
|
|
526
|
+
if not replaced_indices:
|
|
527
|
+
is_online = self.offline_duration < self.outage_grace_period
|
|
528
|
+
|
|
529
|
+
self._housekeep_counter += 1
|
|
530
|
+
duration = time.time() - housekeep_start_time
|
|
531
|
+
kwargs = dict(
|
|
532
|
+
dead_pool_indices=dead_pool_indices,
|
|
533
|
+
replaced_indices=replaced_indices,
|
|
534
|
+
offline_duration=self.offline_duration,
|
|
535
|
+
)
|
|
536
|
+
if is_online:
|
|
537
|
+
self.on_housekeep(duration, **kwargs)
|
|
538
|
+
time.sleep(self.housekeep_interval)
|
|
539
|
+
else:
|
|
515
540
|
self.shutdown()
|
|
516
|
-
self._housekeep_counter += 1
|
|
517
541
|
self.on_housekeep(
|
|
518
|
-
|
|
542
|
+
duration,
|
|
519
543
|
interface.EnvironmentOutageError(
|
|
520
|
-
environment=self,
|
|
521
|
-
|
|
522
|
-
|
|
544
|
+
environment=self, offline_duration=self.offline_duration
|
|
545
|
+
),
|
|
546
|
+
**kwargs
|
|
523
547
|
)
|
|
524
|
-
break
|
|
525
|
-
self._housekeep_counter += 1
|
|
526
|
-
self.on_housekeep(time.time() - housekeep_start_time)
|
|
527
|
-
time.sleep(self.housekeep_interval)
|
|
528
548
|
|
|
529
|
-
def _replace_dead_sandboxes(self, dead_pool_indices: list[int]) ->
|
|
549
|
+
def _replace_dead_sandboxes(self, dead_pool_indices: list[int]) -> list[int]:
|
|
530
550
|
"""Replaces a dead sandbox with a new one.
|
|
531
551
|
|
|
532
552
|
Args:
|
|
533
553
|
dead_pool_indices: The indices of the dead sandboxes to replace.
|
|
534
554
|
|
|
535
555
|
Returns:
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
Raises:
|
|
539
|
-
interface.EnvironmentOutageError: If the XBox sandboxes cannot be created
|
|
540
|
-
within the wait time specified by `xbox_outage_grace_period`.
|
|
556
|
+
Successfully replaced indices.
|
|
541
557
|
"""
|
|
542
558
|
pg.logging.warning(
|
|
543
559
|
'[%s]: %s maintenance: '
|
|
@@ -548,21 +564,31 @@ class BaseEnvironment(interface.Environment):
|
|
|
548
564
|
)
|
|
549
565
|
def _replace(i: int):
|
|
550
566
|
generation = int(self._sandbox_pool[i].id.sandbox_id.split(':')[1])
|
|
551
|
-
self._sandbox_pool[i] = self.
|
|
552
|
-
f'{i}:{generation + 1}', shutdown_env_upon_outage=False
|
|
553
|
-
)
|
|
567
|
+
self._sandbox_pool[i] = self._bring_up_sandbox(f'{i}:{generation + 1}')
|
|
554
568
|
|
|
555
569
|
# TODO(daiyip): Consider to loose the condition to allow some dead
|
|
556
570
|
# sandboxes to be replaced successfully.
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
571
|
+
replaced_indices = []
|
|
572
|
+
for index, _, error in lf.concurrent_map(
|
|
573
|
+
_replace, dead_pool_indices,
|
|
574
|
+
max_workers=min(
|
|
575
|
+
self.pool_operation_max_parallelism,
|
|
576
|
+
len(dead_pool_indices)
|
|
577
|
+
),
|
|
578
|
+
):
|
|
579
|
+
if error is None:
|
|
580
|
+
replaced_indices.append(index)
|
|
581
|
+
|
|
582
|
+
pg.logging.warning(
|
|
583
|
+
'[%s]: %s maintenance: '
|
|
584
|
+
'%d/%d dead sandbox(es) have been replaced with new ones. (slots=%s)',
|
|
585
|
+
self.id,
|
|
586
|
+
self.__class__.__name__,
|
|
587
|
+
len(replaced_indices),
|
|
588
|
+
len(dead_pool_indices),
|
|
589
|
+
replaced_indices
|
|
590
|
+
)
|
|
591
|
+
return replaced_indices
|
|
566
592
|
|
|
567
593
|
#
|
|
568
594
|
# Event handlers subclasses can override.
|
|
@@ -584,12 +610,20 @@ class BaseEnvironment(interface.Environment):
|
|
|
584
610
|
def on_housekeep(
|
|
585
611
|
self,
|
|
586
612
|
duration: float,
|
|
587
|
-
error: BaseException | None = None
|
|
613
|
+
error: BaseException | None = None,
|
|
614
|
+
**kwargs
|
|
588
615
|
) -> None:
|
|
589
616
|
"""Called when the environment finishes a round of housekeeping."""
|
|
590
617
|
housekeep_counter = self.housekeep_counter
|
|
591
618
|
for handler in self.event_handlers:
|
|
592
|
-
handler.on_environment_housekeep(
|
|
619
|
+
handler.on_environment_housekeep(
|
|
620
|
+
self, housekeep_counter, duration, error, **kwargs
|
|
621
|
+
)
|
|
622
|
+
|
|
623
|
+
def on_shutting_down(self) -> None:
|
|
624
|
+
"""Called when the environment is shutting down."""
|
|
625
|
+
for handler in self.event_handlers:
|
|
626
|
+
handler.on_environment_shutting_down(self, self.offline_duration)
|
|
593
627
|
|
|
594
628
|
def on_shutdown(
|
|
595
629
|
self,
|
langfun/env/base_feature.py
CHANGED
|
@@ -186,11 +186,12 @@ class BaseFeature(interface.Feature):
|
|
|
186
186
|
def on_housekeep(
|
|
187
187
|
self,
|
|
188
188
|
duration: float,
|
|
189
|
-
error: BaseException | None = None
|
|
189
|
+
error: BaseException | None = None,
|
|
190
|
+
**kwargs
|
|
190
191
|
) -> None:
|
|
191
192
|
"""Called when the feature has done housekeeping."""
|
|
192
193
|
self.sandbox.on_feature_housekeep(
|
|
193
|
-
self, self._housekeep_counter, duration, error
|
|
194
|
+
self, self._housekeep_counter, duration, error, **kwargs
|
|
194
195
|
)
|
|
195
196
|
|
|
196
197
|
def on_setup_session(
|
langfun/env/base_sandbox.py
CHANGED
|
@@ -706,7 +706,6 @@ class BaseSandbox(interface.Sandbox):
|
|
|
706
706
|
while self._status not in (self.Status.SHUTTING_DOWN, self.Status.OFFLINE):
|
|
707
707
|
housekeep_start = time.time()
|
|
708
708
|
if self.keepalive_interval is not None:
|
|
709
|
-
|
|
710
709
|
if time.time() - last_ping > self.keepalive_interval:
|
|
711
710
|
try:
|
|
712
711
|
self.ping()
|
|
@@ -796,13 +795,14 @@ class BaseSandbox(interface.Sandbox):
|
|
|
796
795
|
def on_housekeep(
|
|
797
796
|
self,
|
|
798
797
|
duration: float,
|
|
799
|
-
error: BaseException | None = None
|
|
798
|
+
error: BaseException | None = None,
|
|
799
|
+
**kwargs
|
|
800
800
|
) -> None:
|
|
801
801
|
"""Called when the sandbox finishes a round of housekeeping."""
|
|
802
802
|
counter = self._housekeep_counter
|
|
803
803
|
for handler in self._event_handlers:
|
|
804
804
|
handler.on_sandbox_housekeep(
|
|
805
|
-
self.environment, self, counter, duration, error
|
|
805
|
+
self.environment, self, counter, duration, error, **kwargs
|
|
806
806
|
)
|
|
807
807
|
|
|
808
808
|
def on_feature_setup(
|
langfun/env/base_test.py
CHANGED
|
@@ -280,7 +280,11 @@ class EnvironmentTests(unittest.TestCase):
|
|
|
280
280
|
with self.assertRaises(interface.SandboxStateError):
|
|
281
281
|
sb.shell('bad command', raise_error=interface.SandboxStateError)
|
|
282
282
|
self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
|
|
283
|
-
|
|
283
|
+
sb_offline_time = time.time()
|
|
284
|
+
while time.time() - sb_offline_time < 10:
|
|
285
|
+
if not env.is_online:
|
|
286
|
+
break
|
|
287
|
+
time.sleep(0.5)
|
|
284
288
|
self.assertFalse(env.is_online)
|
|
285
289
|
|
|
286
290
|
|
|
@@ -1177,6 +1181,7 @@ class SandboxActivityTests(unittest.TestCase):
|
|
|
1177
1181
|
sb.shell('test_feature')
|
|
1178
1182
|
sb.remove_event_handler(event_handler)
|
|
1179
1183
|
events = list(event_handler.logs)
|
|
1184
|
+
sb.wait_until_not(interface.Sandbox.Status.SETTING_UP)
|
|
1180
1185
|
self.assertGreater(len(events), 0)
|
|
1181
1186
|
with env.sandbox('session2') as sb:
|
|
1182
1187
|
sb.shell('test_feature')
|
|
@@ -76,7 +76,16 @@ class _FeatureEventHandler:
|
|
|
76
76
|
duration: float,
|
|
77
77
|
error: BaseException | None
|
|
78
78
|
) -> None:
|
|
79
|
-
"""Called when a sandbox feature is setup.
|
|
79
|
+
"""Called when a sandbox feature is setup.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
environment: The environment.
|
|
83
|
+
sandbox: The sandbox.
|
|
84
|
+
feature: The feature.
|
|
85
|
+
duration: The feature setup duration in seconds.
|
|
86
|
+
error: The error happened during the feature setup. If None,
|
|
87
|
+
the feature setup performed normally.
|
|
88
|
+
"""
|
|
80
89
|
|
|
81
90
|
def on_feature_teardown(
|
|
82
91
|
self,
|
|
@@ -86,7 +95,16 @@ class _FeatureEventHandler:
|
|
|
86
95
|
duration: float,
|
|
87
96
|
error: BaseException | None
|
|
88
97
|
) -> None:
|
|
89
|
-
"""Called when a sandbox feature is teardown.
|
|
98
|
+
"""Called when a sandbox feature is teardown.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
environment: The environment.
|
|
102
|
+
sandbox: The sandbox.
|
|
103
|
+
feature: The feature.
|
|
104
|
+
duration: The feature teardown duration in seconds.
|
|
105
|
+
error: The error happened during the feature teardown. If None,
|
|
106
|
+
the feature teardown performed normally.
|
|
107
|
+
"""
|
|
90
108
|
|
|
91
109
|
def on_feature_teardown_session(
|
|
92
110
|
self,
|
|
@@ -97,7 +115,17 @@ class _FeatureEventHandler:
|
|
|
97
115
|
duration: float,
|
|
98
116
|
error: BaseException | None
|
|
99
117
|
) -> None:
|
|
100
|
-
"""Called when a feature is teardown with a session.
|
|
118
|
+
"""Called when a feature is teardown with a session.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
environment: The environment.
|
|
122
|
+
sandbox: The sandbox.
|
|
123
|
+
feature: The feature.
|
|
124
|
+
session_id: The session ID.
|
|
125
|
+
duration: The feature teardown session duration in seconds.
|
|
126
|
+
error: The error happened during the feature teardown session. If
|
|
127
|
+
None, the feature teardown session performed normally.
|
|
128
|
+
"""
|
|
101
129
|
|
|
102
130
|
def on_feature_setup_session(
|
|
103
131
|
self,
|
|
@@ -106,9 +134,19 @@ class _FeatureEventHandler:
|
|
|
106
134
|
feature: Feature,
|
|
107
135
|
session_id: str | None,
|
|
108
136
|
duration: float,
|
|
109
|
-
error: BaseException | None
|
|
137
|
+
error: BaseException | None,
|
|
110
138
|
) -> None:
|
|
111
|
-
"""Called when a feature is setup with a session.
|
|
139
|
+
"""Called when a feature is setup with a session.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
environment: The environment.
|
|
143
|
+
sandbox: The sandbox.
|
|
144
|
+
feature: The feature.
|
|
145
|
+
session_id: The session ID.
|
|
146
|
+
duration: The feature setup session duration in seconds.
|
|
147
|
+
error: The error happened during the feature setup session. If
|
|
148
|
+
None, the feature setup session performed normally.
|
|
149
|
+
"""
|
|
112
150
|
|
|
113
151
|
def on_feature_housekeep(
|
|
114
152
|
self,
|
|
@@ -117,9 +155,21 @@ class _FeatureEventHandler:
|
|
|
117
155
|
feature: Feature,
|
|
118
156
|
counter: int,
|
|
119
157
|
duration: float,
|
|
120
|
-
error: BaseException | None
|
|
158
|
+
error: BaseException | None,
|
|
159
|
+
**kwargs,
|
|
121
160
|
) -> None:
|
|
122
|
-
"""Called when a sandbox feature is housekeeping.
|
|
161
|
+
"""Called when a sandbox feature is housekeeping.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
environment: The environment.
|
|
165
|
+
sandbox: The sandbox.
|
|
166
|
+
feature: The feature.
|
|
167
|
+
counter: Zero-based counter of the housekeeping round.
|
|
168
|
+
duration: The feature housekeeping duration in seconds.
|
|
169
|
+
error: The error happened during the feature housekeeping. If None, the
|
|
170
|
+
feature housekeeping normally.
|
|
171
|
+
**kwargs: Feature-specific properties computed during housekeeping.
|
|
172
|
+
"""
|
|
123
173
|
|
|
124
174
|
|
|
125
175
|
class _SandboxEventHandler(_FeatureEventHandler, _SessionEventHandler):
|
|
@@ -210,7 +260,8 @@ class _SandboxEventHandler(_FeatureEventHandler, _SessionEventHandler):
|
|
|
210
260
|
sandbox: Sandbox,
|
|
211
261
|
counter: int,
|
|
212
262
|
duration: float,
|
|
213
|
-
error: BaseException | None
|
|
263
|
+
error: BaseException | None,
|
|
264
|
+
**kwargs
|
|
214
265
|
) -> None:
|
|
215
266
|
"""Called when a sandbox finishes a round of housekeeping.
|
|
216
267
|
|
|
@@ -221,6 +272,7 @@ class _SandboxEventHandler(_FeatureEventHandler, _SessionEventHandler):
|
|
|
221
272
|
duration: The sandbox housekeeping duration in seconds.
|
|
222
273
|
error: The error that caused the sandbox to housekeeping. If None, the
|
|
223
274
|
sandbox housekeeping normally.
|
|
275
|
+
**kwargs: Sandbox-specific properties computed during housekeeping.
|
|
224
276
|
"""
|
|
225
277
|
|
|
226
278
|
|
|
@@ -254,7 +306,8 @@ class EventHandler(_SandboxEventHandler):
|
|
|
254
306
|
environment: Environment,
|
|
255
307
|
counter: int,
|
|
256
308
|
duration: float,
|
|
257
|
-
error: BaseException | None
|
|
309
|
+
error: BaseException | None,
|
|
310
|
+
**kwargs
|
|
258
311
|
) -> None:
|
|
259
312
|
"""Called when the environment finishes a round of housekeeping.
|
|
260
313
|
|
|
@@ -264,6 +317,19 @@ class EventHandler(_SandboxEventHandler):
|
|
|
264
317
|
duration: The environment start duration in seconds.
|
|
265
318
|
error: The error that failed the housekeeping. If None, the
|
|
266
319
|
housekeeping succeeded.
|
|
320
|
+
**kwargs: Environment-specific properties computed during housekeeping.
|
|
321
|
+
"""
|
|
322
|
+
|
|
323
|
+
def on_environment_shutting_down(
|
|
324
|
+
self,
|
|
325
|
+
environment: Environment,
|
|
326
|
+
offline_duration: float,
|
|
327
|
+
) -> None:
|
|
328
|
+
"""Called when the environment is shutting down.
|
|
329
|
+
|
|
330
|
+
Args:
|
|
331
|
+
environment: The environment.
|
|
332
|
+
offline_duration: The environment offline duration in seconds.
|
|
267
333
|
"""
|
|
268
334
|
|
|
269
335
|
def on_environment_shutdown(
|
|
@@ -105,7 +105,9 @@ class EventLogger(pg.Object, base.EventHandler):
|
|
|
105
105
|
error: BaseException | None,
|
|
106
106
|
) -> str:
|
|
107
107
|
if error is not None:
|
|
108
|
-
message =
|
|
108
|
+
message = (
|
|
109
|
+
f'{message} with error: {pg.utils.ErrorInfo.from_exception(error)}'
|
|
110
|
+
)
|
|
109
111
|
return message
|
|
110
112
|
|
|
111
113
|
def _keep(
|
|
@@ -133,6 +135,20 @@ class EventLogger(pg.Object, base.EventHandler):
|
|
|
133
135
|
styles=['bold'],
|
|
134
136
|
)
|
|
135
137
|
|
|
138
|
+
def on_environment_shutting_down(
|
|
139
|
+
self,
|
|
140
|
+
environment: base.Environment,
|
|
141
|
+
offline_duration: float,
|
|
142
|
+
) -> None:
|
|
143
|
+
"""Called when the environment is shutting down."""
|
|
144
|
+
self._print(
|
|
145
|
+
f'[{environment.id}] environment shutting down '
|
|
146
|
+
f'(offline_duration={offline_duration:.2f} seconds)',
|
|
147
|
+
error=None,
|
|
148
|
+
color='green',
|
|
149
|
+
styles=['bold'],
|
|
150
|
+
)
|
|
151
|
+
|
|
136
152
|
def on_environment_start(
|
|
137
153
|
self,
|
|
138
154
|
environment: base.Environment,
|
|
@@ -153,13 +169,15 @@ class EventLogger(pg.Object, base.EventHandler):
|
|
|
153
169
|
environment: base.Environment,
|
|
154
170
|
counter: int,
|
|
155
171
|
duration: float,
|
|
156
|
-
error: BaseException | None
|
|
172
|
+
error: BaseException | None,
|
|
173
|
+
**kwargs
|
|
157
174
|
) -> None:
|
|
158
175
|
"""Called when the environment is housekeeping."""
|
|
159
176
|
if self.housekeep_status:
|
|
160
177
|
self._print(
|
|
161
|
-
f'[{environment.id}] environment housekeeping complete'
|
|
162
|
-
f'(counter={counter}, duration={duration:.2f} seconds
|
|
178
|
+
f'[{environment.id}] environment housekeeping complete '
|
|
179
|
+
f'(counter={counter}, duration={duration:.2f} seconds, '
|
|
180
|
+
f'housekeep_info={kwargs})',
|
|
163
181
|
error=error,
|
|
164
182
|
color='green',
|
|
165
183
|
)
|
|
@@ -246,13 +264,15 @@ class EventLogger(pg.Object, base.EventHandler):
|
|
|
246
264
|
sandbox: base.Sandbox,
|
|
247
265
|
counter: int,
|
|
248
266
|
duration: float,
|
|
249
|
-
error: BaseException | None
|
|
267
|
+
error: BaseException | None,
|
|
268
|
+
**kwargs
|
|
250
269
|
) -> None:
|
|
251
270
|
"""Called when a sandbox feature is housekeeping."""
|
|
252
271
|
if self.sandbox_status and self.housekeep_status:
|
|
253
272
|
self._print(
|
|
254
273
|
f'[{sandbox.id}] sandbox housekeeping complete '
|
|
255
|
-
f'(counter={counter}, duration={duration:.2f} seconds
|
|
274
|
+
f'(counter={counter}, duration={duration:.2f} seconds, '
|
|
275
|
+
f'housekeep_info={kwargs})',
|
|
256
276
|
error=error,
|
|
257
277
|
color='white',
|
|
258
278
|
)
|
|
@@ -334,13 +354,15 @@ class EventLogger(pg.Object, base.EventHandler):
|
|
|
334
354
|
feature: base.Feature,
|
|
335
355
|
counter: int,
|
|
336
356
|
duration: float,
|
|
337
|
-
error: BaseException | None
|
|
357
|
+
error: BaseException | None,
|
|
358
|
+
**kwargs
|
|
338
359
|
) -> None:
|
|
339
360
|
"""Called when a sandbox feature is housekeeping."""
|
|
340
361
|
if self.feature_status and self.housekeep_status:
|
|
341
362
|
self._print(
|
|
342
363
|
f'[{sandbox.id}/<idle>/{feature.name}] feature housekeeping complete '
|
|
343
|
-
f'(counter={counter}, (duration={duration:.2f} seconds
|
|
364
|
+
f'(counter={counter}, (duration={duration:.2f} seconds, '
|
|
365
|
+
f'housekeep_info={kwargs})',
|
|
344
366
|
error=error,
|
|
345
367
|
color='white',
|
|
346
368
|
)
|
|
@@ -125,6 +125,7 @@ class EventLoggerTest(unittest.TestCase):
|
|
|
125
125
|
unexpected_substrings=[
|
|
126
126
|
'environment starting',
|
|
127
127
|
'environment started',
|
|
128
|
+
'environment shutting down',
|
|
128
129
|
'environment shutdown',
|
|
129
130
|
'environment housekeeping',
|
|
130
131
|
'sandbox started',
|
|
@@ -143,6 +144,7 @@ class EventLoggerTest(unittest.TestCase):
|
|
|
143
144
|
expected_substrings=[
|
|
144
145
|
'environment starting',
|
|
145
146
|
'environment started',
|
|
147
|
+
'environment shutting down',
|
|
146
148
|
'environment shutdown',
|
|
147
149
|
'environment housekeeping',
|
|
148
150
|
],
|
|
@@ -166,6 +168,7 @@ class EventLoggerTest(unittest.TestCase):
|
|
|
166
168
|
expected_substrings=[
|
|
167
169
|
'environment starting',
|
|
168
170
|
'environment started',
|
|
171
|
+
'environment shutting down',
|
|
169
172
|
'environment shutdown',
|
|
170
173
|
'environment housekeeping',
|
|
171
174
|
'feature setup complete',
|
|
@@ -191,6 +194,7 @@ class EventLoggerTest(unittest.TestCase):
|
|
|
191
194
|
expected_substrings=[
|
|
192
195
|
'environment starting',
|
|
193
196
|
'environment started',
|
|
197
|
+
'environment shutting down',
|
|
194
198
|
'environment shutdown',
|
|
195
199
|
'environment housekeeping',
|
|
196
200
|
'environment stats',
|
|
@@ -217,6 +221,7 @@ class EventLoggerTest(unittest.TestCase):
|
|
|
217
221
|
expected_substrings=[
|
|
218
222
|
'environment starting',
|
|
219
223
|
'environment started',
|
|
224
|
+
'environment shutting down',
|
|
220
225
|
'environment shutdown',
|
|
221
226
|
'environment stats',
|
|
222
227
|
'environment housekeeping',
|
|
@@ -243,6 +248,7 @@ class EventLoggerTest(unittest.TestCase):
|
|
|
243
248
|
expected_substrings=[
|
|
244
249
|
'environment starting',
|
|
245
250
|
'environment started',
|
|
251
|
+
'environment shutting down',
|
|
246
252
|
'environment shutdown',
|
|
247
253
|
'environment stats',
|
|
248
254
|
'sandbox started',
|
|
@@ -269,6 +275,7 @@ class EventLoggerTest(unittest.TestCase):
|
|
|
269
275
|
expected_substrings=[
|
|
270
276
|
'environment starting',
|
|
271
277
|
'environment started',
|
|
278
|
+
'environment shutting down',
|
|
272
279
|
'environment shutdown',
|
|
273
280
|
'environment housekeeping',
|
|
274
281
|
],
|