langfun 0.1.2.dev202509280803__py3-none-any.whl → 0.1.2.dev202509300805__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/env/base_environment.py +19 -7
- langfun/env/base_sandbox.py +31 -8
- langfun/env/base_test.py +134 -102
- langfun/env/event_handlers/__init__.py +2 -0
- langfun/env/event_handlers/base.py +13 -0
- langfun/env/event_handlers/event_logger.py +45 -7
- langfun/env/event_handlers/event_logger_test.py +8 -0
- langfun/env/event_handlers/metric_writer.py +545 -0
- langfun/env/event_handlers/metric_writer_test.py +160 -0
- langfun/env/test_utils.py +6 -3
- {langfun-0.1.2.dev202509280803.dist-info → langfun-0.1.2.dev202509300805.dist-info}/METADATA +1 -1
- {langfun-0.1.2.dev202509280803.dist-info → langfun-0.1.2.dev202509300805.dist-info}/RECORD +15 -13
- {langfun-0.1.2.dev202509280803.dist-info → langfun-0.1.2.dev202509300805.dist-info}/WHEEL +0 -0
- {langfun-0.1.2.dev202509280803.dist-info → langfun-0.1.2.dev202509300805.dist-info}/licenses/LICENSE +0 -0
- {langfun-0.1.2.dev202509280803.dist-info → langfun-0.1.2.dev202509300805.dist-info}/top_level.txt +0 -0
langfun/env/base_environment.py
CHANGED
|
@@ -221,7 +221,7 @@ class BaseEnvironment(interface.Environment):
|
|
|
221
221
|
self._sandbox_pool = [None] * self.min_pool_size
|
|
222
222
|
for i, sandbox, _ in lf.concurrent_map(
|
|
223
223
|
lambda i: self._bring_up_sandbox_with_retry(
|
|
224
|
-
sandbox_id=
|
|
224
|
+
sandbox_id=f'{i}:0', shutdown_env_upon_outage=False
|
|
225
225
|
),
|
|
226
226
|
range(self.min_pool_size),
|
|
227
227
|
silence_on_errors=None,
|
|
@@ -335,6 +335,7 @@ class BaseEnvironment(interface.Environment):
|
|
|
335
335
|
f'it is in {self._status.value!r} status.'
|
|
336
336
|
)
|
|
337
337
|
|
|
338
|
+
self.on_starting()
|
|
338
339
|
starting_time = time.time()
|
|
339
340
|
try:
|
|
340
341
|
self._start()
|
|
@@ -359,11 +360,12 @@ class BaseEnvironment(interface.Environment):
|
|
|
359
360
|
|
|
360
361
|
self._set_status(self.Status.SHUTTING_DOWN)
|
|
361
362
|
|
|
363
|
+
shutting_down_time = time.time()
|
|
362
364
|
try:
|
|
363
365
|
self._shutdown()
|
|
364
|
-
self.on_shutdown()
|
|
366
|
+
self.on_shutdown(duration=time.time() - shutting_down_time)
|
|
365
367
|
except BaseException as e: # pylint: disable=broad-except
|
|
366
|
-
self.on_shutdown(error=e)
|
|
368
|
+
self.on_shutdown(duration=time.time() - shutting_down_time, error=e)
|
|
367
369
|
raise e
|
|
368
370
|
|
|
369
371
|
#
|
|
@@ -412,7 +414,8 @@ class BaseEnvironment(interface.Environment):
|
|
|
412
414
|
else:
|
|
413
415
|
try:
|
|
414
416
|
sandbox = self._bring_up_sandbox(
|
|
415
|
-
sandbox_id=
|
|
417
|
+
sandbox_id=f'{self._increment_sandbox_id()}:0',
|
|
418
|
+
set_acquired=True,
|
|
416
419
|
)
|
|
417
420
|
# Append is atomic and does not require locking.
|
|
418
421
|
self._sandbox_pool.append(sandbox)
|
|
@@ -544,8 +547,9 @@ class BaseEnvironment(interface.Environment):
|
|
|
544
547
|
len(dead_pool_indices),
|
|
545
548
|
)
|
|
546
549
|
def _replace(i: int):
|
|
550
|
+
generation = int(self._sandbox_pool[i].id.sandbox_id.split(':')[1])
|
|
547
551
|
self._sandbox_pool[i] = self._bring_up_sandbox_with_retry(
|
|
548
|
-
|
|
552
|
+
f'{i}:{generation + 1}', shutdown_env_upon_outage=False
|
|
549
553
|
)
|
|
550
554
|
|
|
551
555
|
# TODO(daiyip): Consider to loose the condition to allow some dead
|
|
@@ -564,6 +568,11 @@ class BaseEnvironment(interface.Environment):
|
|
|
564
568
|
# Event handlers subclasses can override.
|
|
565
569
|
#
|
|
566
570
|
|
|
571
|
+
def on_starting(self) -> None:
|
|
572
|
+
"""Called when the environment is getting started."""
|
|
573
|
+
for handler in self.event_handlers:
|
|
574
|
+
handler.on_environment_starting(self)
|
|
575
|
+
|
|
567
576
|
def on_start(
|
|
568
577
|
self,
|
|
569
578
|
duration: float, error: BaseException | None = None
|
|
@@ -582,8 +591,11 @@ class BaseEnvironment(interface.Environment):
|
|
|
582
591
|
for handler in self.event_handlers:
|
|
583
592
|
handler.on_environment_housekeep(self, housekeep_counter, duration, error)
|
|
584
593
|
|
|
585
|
-
def on_shutdown(
|
|
594
|
+
def on_shutdown(
|
|
595
|
+
self,
|
|
596
|
+
duration: float,
|
|
597
|
+
error: BaseException | None = None) -> None:
|
|
586
598
|
"""Called when the environment is shutdown."""
|
|
587
599
|
lifetime = (time.time() - self.start_time) if self.start_time else 0.0
|
|
588
600
|
for handler in self.event_handlers:
|
|
589
|
-
handler.on_environment_shutdown(self, lifetime, error)
|
|
601
|
+
handler.on_environment_shutdown(self, duration, lifetime, error)
|
langfun/env/base_sandbox.py
CHANGED
|
@@ -418,6 +418,7 @@ class BaseSandbox(interface.Sandbox):
|
|
|
418
418
|
self.end_session(shutdown_sandbox=True)
|
|
419
419
|
return
|
|
420
420
|
|
|
421
|
+
shutting_down_time = time.time()
|
|
421
422
|
self._set_status(interface.Sandbox.Status.SHUTTING_DOWN)
|
|
422
423
|
|
|
423
424
|
if (self._housekeep_thread is not None
|
|
@@ -429,7 +430,10 @@ class BaseSandbox(interface.Sandbox):
|
|
|
429
430
|
try:
|
|
430
431
|
self._shutdown()
|
|
431
432
|
self._set_status(interface.Sandbox.Status.OFFLINE)
|
|
432
|
-
self.on_shutdown(
|
|
433
|
+
self.on_shutdown(
|
|
434
|
+
duration=time.time() - shutting_down_time,
|
|
435
|
+
error=teardown_error
|
|
436
|
+
)
|
|
433
437
|
shutdown_error = None
|
|
434
438
|
except BaseException as e: # pylint: disable=broad-except
|
|
435
439
|
shutdown_error = e
|
|
@@ -439,7 +443,10 @@ class BaseSandbox(interface.Sandbox):
|
|
|
439
443
|
'[%s]: Sandbox shutdown with error: %s',
|
|
440
444
|
self.id, e
|
|
441
445
|
)
|
|
442
|
-
self.on_shutdown(
|
|
446
|
+
self.on_shutdown(
|
|
447
|
+
duration=time.time() - shutting_down_time,
|
|
448
|
+
error=teardown_error or shutdown_error
|
|
449
|
+
)
|
|
443
450
|
|
|
444
451
|
# We raise non-state errors to the user following timely order, so the user
|
|
445
452
|
# code could be surfaced and handled properly.
|
|
@@ -591,6 +598,7 @@ class BaseSandbox(interface.Sandbox):
|
|
|
591
598
|
# Set sandbox status to EXITING_SESSION to avoid re-entry.
|
|
592
599
|
self._set_status(self.Status.EXITING_SESSION)
|
|
593
600
|
shutdown_sandbox = shutdown_sandbox or not self.reusable
|
|
601
|
+
ending_time = time.time()
|
|
594
602
|
|
|
595
603
|
# Teardown features for the current session.
|
|
596
604
|
end_session_error = self._end_session()
|
|
@@ -617,7 +625,9 @@ class BaseSandbox(interface.Sandbox):
|
|
|
617
625
|
self.shutdown()
|
|
618
626
|
|
|
619
627
|
# End session before setting up the next session.
|
|
620
|
-
self.on_session_end(
|
|
628
|
+
self.on_session_end(
|
|
629
|
+
previous_session_id, duration=time.time() - ending_time
|
|
630
|
+
)
|
|
621
631
|
|
|
622
632
|
# Mark the sandbox as setting up to prevent it from being acquired by
|
|
623
633
|
# other threads.
|
|
@@ -628,7 +638,9 @@ class BaseSandbox(interface.Sandbox):
|
|
|
628
638
|
threading.Thread(target=_setup_next_session).start()
|
|
629
639
|
else:
|
|
630
640
|
# End session before reporting sandbox status change.
|
|
631
|
-
self.on_session_end(
|
|
641
|
+
self.on_session_end(
|
|
642
|
+
previous_session_id, duration=time.time() - ending_time
|
|
643
|
+
)
|
|
632
644
|
|
|
633
645
|
# If shutdown is requested, mark the sandbox as acquired to prevent it
|
|
634
646
|
# from being acquired by other threads.
|
|
@@ -639,7 +651,11 @@ class BaseSandbox(interface.Sandbox):
|
|
|
639
651
|
|
|
640
652
|
# Otherwise, shutdown the sandbox.
|
|
641
653
|
else:
|
|
642
|
-
self.on_session_end(
|
|
654
|
+
self.on_session_end(
|
|
655
|
+
previous_session_id,
|
|
656
|
+
duration=time.time() - ending_time,
|
|
657
|
+
error=self.state_errors[0]
|
|
658
|
+
)
|
|
643
659
|
self._set_status(interface.Sandbox.Status.ACQUIRED)
|
|
644
660
|
shutdown_sandbox = True
|
|
645
661
|
|
|
@@ -762,14 +778,20 @@ class BaseSandbox(interface.Sandbox):
|
|
|
762
778
|
time.time() - self._status_start_time
|
|
763
779
|
)
|
|
764
780
|
|
|
765
|
-
def on_shutdown(
|
|
781
|
+
def on_shutdown(
|
|
782
|
+
self,
|
|
783
|
+
duration: float,
|
|
784
|
+
error: BaseException | None = None
|
|
785
|
+
) -> None:
|
|
766
786
|
"""Called when the sandbox is shutdown."""
|
|
767
787
|
if self._start_time is None:
|
|
768
788
|
lifetime = 0.0
|
|
769
789
|
else:
|
|
770
790
|
lifetime = time.time() - self._start_time
|
|
771
791
|
for handler in self._event_handlers:
|
|
772
|
-
handler.on_sandbox_shutdown(
|
|
792
|
+
handler.on_sandbox_shutdown(
|
|
793
|
+
self.environment, self, duration, lifetime, error
|
|
794
|
+
)
|
|
773
795
|
|
|
774
796
|
def on_housekeep(
|
|
775
797
|
self,
|
|
@@ -880,13 +902,14 @@ class BaseSandbox(interface.Sandbox):
|
|
|
880
902
|
def on_session_end(
|
|
881
903
|
self,
|
|
882
904
|
session_id: str,
|
|
905
|
+
duration: float,
|
|
883
906
|
error: BaseException | None = None
|
|
884
907
|
) -> None:
|
|
885
908
|
"""Called when the user session ends."""
|
|
886
909
|
lifetime = time.time() - self._session_start_time
|
|
887
910
|
for handler in self._event_handlers:
|
|
888
911
|
handler.on_session_end(
|
|
889
|
-
self.environment, self, session_id, lifetime, error
|
|
912
|
+
self.environment, self, session_id, duration, lifetime, error
|
|
890
913
|
)
|
|
891
914
|
|
|
892
915
|
|
langfun/env/base_test.py
CHANGED
|
@@ -381,34 +381,34 @@ class SandboxStatusTests(unittest.TestCase):
|
|
|
381
381
|
self.assertEqual(
|
|
382
382
|
self.event_handler.logs,
|
|
383
383
|
[
|
|
384
|
-
'[testing-env/0] shell: "feature1" setup',
|
|
385
|
-
'[testing-env/0/feature1] feature setup',
|
|
386
|
-
'[testing-env/0] shell: "feature2" setup',
|
|
387
|
-
'[testing-env/0/feature2] feature setup',
|
|
388
|
-
'[testing-env/0] shell: "feature1" setup session',
|
|
389
|
-
'[testing-env/0/feature1] feature setup session',
|
|
390
|
-
'[testing-env/0] shell: "feature2" setup session',
|
|
391
|
-
'[testing-env/0/feature2] feature setup session',
|
|
392
|
-
'[testing-env/0] created -> ready',
|
|
393
|
-
'[testing-env/0] sandbox started',
|
|
384
|
+
'[testing-env/0:0] shell: "feature1" setup',
|
|
385
|
+
'[testing-env/0:0/feature1] feature setup',
|
|
386
|
+
'[testing-env/0:0] shell: "feature2" setup',
|
|
387
|
+
'[testing-env/0:0/feature2] feature setup',
|
|
388
|
+
'[testing-env/0:0] shell: "feature1" setup session',
|
|
389
|
+
'[testing-env/0:0/feature1] feature setup session',
|
|
390
|
+
'[testing-env/0:0] shell: "feature2" setup session',
|
|
391
|
+
'[testing-env/0:0/feature2] feature setup session',
|
|
392
|
+
'[testing-env/0:0] created -> ready',
|
|
393
|
+
'[testing-env/0:0] sandbox started',
|
|
394
394
|
'[testing-env] environment started',
|
|
395
|
-
'[testing-env/0] ready -> acquired',
|
|
396
|
-
'[testing-env/0] acquired -> setting_up',
|
|
397
|
-
'[testing-env/0] setting_up -> in_session',
|
|
398
|
-
"[testing-env/0] session 'session1' started",
|
|
399
|
-
'[testing-env/0/session1] shell: echo "hello"',
|
|
400
|
-
'[testing-env/0] in_session -> exiting_session',
|
|
401
|
-
'[testing-env/0/session1] shell: "feature1" teardown session',
|
|
402
|
-
'[testing-env/0/feature1] feature teardown session',
|
|
403
|
-
'[testing-env/0/session1] shell: "feature2" teardown session',
|
|
404
|
-
'[testing-env/0/feature2] feature teardown session',
|
|
405
|
-
"[testing-env/0] session 'session1' ended",
|
|
406
|
-
'[testing-env/0] exiting_session -> setting_up',
|
|
407
|
-
'[testing-env/0] shell: "feature1" setup session',
|
|
408
|
-
'[testing-env/0/feature1] feature setup session',
|
|
409
|
-
'[testing-env/0] shell: "feature2" setup session',
|
|
410
|
-
'[testing-env/0/feature2] feature setup session',
|
|
411
|
-
'[testing-env/0] setting_up -> ready'
|
|
395
|
+
'[testing-env/0:0] ready -> acquired',
|
|
396
|
+
'[testing-env/0:0] acquired -> setting_up',
|
|
397
|
+
'[testing-env/0:0] setting_up -> in_session',
|
|
398
|
+
"[testing-env/0:0] session 'session1' started",
|
|
399
|
+
'[testing-env/0:0/session1] shell: echo "hello"',
|
|
400
|
+
'[testing-env/0:0] in_session -> exiting_session',
|
|
401
|
+
'[testing-env/0:0/session1] shell: "feature1" teardown session',
|
|
402
|
+
'[testing-env/0:0/feature1] feature teardown session',
|
|
403
|
+
'[testing-env/0:0/session1] shell: "feature2" teardown session',
|
|
404
|
+
'[testing-env/0:0/feature2] feature teardown session',
|
|
405
|
+
"[testing-env/0:0] session 'session1' ended",
|
|
406
|
+
'[testing-env/0:0] exiting_session -> setting_up',
|
|
407
|
+
'[testing-env/0:0] shell: "feature1" setup session',
|
|
408
|
+
'[testing-env/0:0/feature1] feature setup session',
|
|
409
|
+
'[testing-env/0:0] shell: "feature2" setup session',
|
|
410
|
+
'[testing-env/0:0/feature2] feature setup session',
|
|
411
|
+
'[testing-env/0:0] setting_up -> ready'
|
|
412
412
|
]
|
|
413
413
|
)
|
|
414
414
|
|
|
@@ -440,17 +440,19 @@ class SandboxStatusTests(unittest.TestCase):
|
|
|
440
440
|
self.assertEqual(
|
|
441
441
|
event_handler.logs,
|
|
442
442
|
[
|
|
443
|
-
|
|
444
|
-
'[testing-env/0
|
|
445
|
-
'[testing-env/0/
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
'[testing-env/0
|
|
449
|
-
'[testing-env/0]
|
|
450
|
-
'[testing-env/0]
|
|
451
|
-
'[testing-env/0
|
|
452
|
-
'[testing-env/0]
|
|
453
|
-
'[testing-env/0]
|
|
443
|
+
# pylint: disable=line-too-long
|
|
444
|
+
'[testing-env/0:0] in_session -> exiting_session',
|
|
445
|
+
'[testing-env/0:0/session1] shell: "test_feature" teardown session',
|
|
446
|
+
'[testing-env/0:0/test_feature] feature teardown session',
|
|
447
|
+
"[testing-env/0:0] session 'session1' ended",
|
|
448
|
+
'[testing-env/0:0] exiting_session -> setting_up',
|
|
449
|
+
'[testing-env/0:0/test_feature] feature setup session with SandboxStateError', # pylint: disable=line-too-long
|
|
450
|
+
'[testing-env/0:0] setting_up -> shutting_down',
|
|
451
|
+
'[testing-env/0:0] shell: "test_feature" teardown',
|
|
452
|
+
'[testing-env/0:0/test_feature] feature teardown',
|
|
453
|
+
'[testing-env/0:0] shutting_down -> offline',
|
|
454
|
+
'[testing-env/0:0] sandbox shutdown'
|
|
455
|
+
# pylint: enable=line-too-long
|
|
454
456
|
]
|
|
455
457
|
)
|
|
456
458
|
|
|
@@ -493,10 +495,10 @@ class SandboxStatusTests(unittest.TestCase):
|
|
|
493
495
|
self.assertEqual(
|
|
494
496
|
self.event_handler.logs,
|
|
495
497
|
[
|
|
496
|
-
'[testing-env/0] sandbox started with SandboxStateError',
|
|
497
|
-
'[testing-env/0] created -> shutting_down',
|
|
498
|
-
'[testing-env/0] shutting_down -> offline',
|
|
499
|
-
'[testing-env/0] sandbox shutdown',
|
|
498
|
+
'[testing-env/0:0] sandbox started with SandboxStateError',
|
|
499
|
+
'[testing-env/0:0] created -> shutting_down',
|
|
500
|
+
'[testing-env/0:0] shutting_down -> offline',
|
|
501
|
+
'[testing-env/0:0] sandbox shutdown',
|
|
500
502
|
'[testing-env] environment started with EnvironmentOutageError',
|
|
501
503
|
'[testing-env] environment shutdown'
|
|
502
504
|
]
|
|
@@ -569,24 +571,24 @@ class SandboxStatusTests(unittest.TestCase):
|
|
|
569
571
|
self.assertEqual(
|
|
570
572
|
self.event_handler.logs,
|
|
571
573
|
[
|
|
572
|
-
'[testing-env/0] shell: "feature1" setup',
|
|
573
|
-
'[testing-env/0/feature1] feature setup',
|
|
574
|
-
'[testing-env/0] shell: "feature2" setup',
|
|
575
|
-
'[testing-env/0/feature2] feature setup',
|
|
576
|
-
'[testing-env/0] shell: "feature1" setup session',
|
|
577
|
-
'[testing-env/0/feature1] feature setup session',
|
|
578
|
-
'[testing-env/0] shell: "feature2" setup session',
|
|
579
|
-
'[testing-env/0/feature2] feature setup session',
|
|
580
|
-
'[testing-env/0] created -> ready',
|
|
581
|
-
'[testing-env/0] sandbox started',
|
|
574
|
+
'[testing-env/0:0] shell: "feature1" setup',
|
|
575
|
+
'[testing-env/0:0/feature1] feature setup',
|
|
576
|
+
'[testing-env/0:0] shell: "feature2" setup',
|
|
577
|
+
'[testing-env/0:0/feature2] feature setup',
|
|
578
|
+
'[testing-env/0:0] shell: "feature1" setup session',
|
|
579
|
+
'[testing-env/0:0/feature1] feature setup session',
|
|
580
|
+
'[testing-env/0:0] shell: "feature2" setup session',
|
|
581
|
+
'[testing-env/0:0/feature2] feature setup session',
|
|
582
|
+
'[testing-env/0:0] created -> ready',
|
|
583
|
+
'[testing-env/0:0] sandbox started',
|
|
582
584
|
'[testing-env] environment started',
|
|
583
|
-
'[testing-env/0] ready -> shutting_down',
|
|
584
|
-
'[testing-env/0] shell: "feature1" teardown',
|
|
585
|
-
'[testing-env/0/feature1] feature teardown',
|
|
586
|
-
'[testing-env/0] shell: "feature2" teardown',
|
|
587
|
-
'[testing-env/0/feature2] feature teardown',
|
|
588
|
-
'[testing-env/0] shutting_down -> offline',
|
|
589
|
-
'[testing-env/0] sandbox shutdown with ValueError',
|
|
585
|
+
'[testing-env/0:0] ready -> shutting_down',
|
|
586
|
+
'[testing-env/0:0] shell: "feature1" teardown',
|
|
587
|
+
'[testing-env/0:0/feature1] feature teardown',
|
|
588
|
+
'[testing-env/0:0] shell: "feature2" teardown',
|
|
589
|
+
'[testing-env/0:0/feature2] feature teardown',
|
|
590
|
+
'[testing-env/0:0] shutting_down -> offline',
|
|
591
|
+
'[testing-env/0:0] sandbox shutdown with ValueError',
|
|
590
592
|
'[testing-env] environment shutdown with ValueError'
|
|
591
593
|
]
|
|
592
594
|
)
|
|
@@ -998,27 +1000,27 @@ class SandboxStatusTests(unittest.TestCase):
|
|
|
998
1000
|
self.assertEqual(
|
|
999
1001
|
self.event_handler.logs,
|
|
1000
1002
|
[
|
|
1001
|
-
'[testing-env/0] shell: "feature1" setup',
|
|
1002
|
-
'[testing-env/0/feature1] feature setup',
|
|
1003
|
-
'[testing-env/0] shell: "feature1" setup session',
|
|
1004
|
-
'[testing-env/0/feature1] feature setup session',
|
|
1005
|
-
'[testing-env/0] created -> ready',
|
|
1006
|
-
'[testing-env/0] sandbox started',
|
|
1003
|
+
'[testing-env/0:0] shell: "feature1" setup',
|
|
1004
|
+
'[testing-env/0:0/feature1] feature setup',
|
|
1005
|
+
'[testing-env/0:0] shell: "feature1" setup session',
|
|
1006
|
+
'[testing-env/0:0/feature1] feature setup session',
|
|
1007
|
+
'[testing-env/0:0] created -> ready',
|
|
1008
|
+
'[testing-env/0:0] sandbox started',
|
|
1007
1009
|
'[testing-env] environment started',
|
|
1008
|
-
'[testing-env/0] ready -> acquired',
|
|
1009
|
-
'[testing-env/0] acquired -> setting_up',
|
|
1010
|
-
'[testing-env/0] setting_up -> in_session',
|
|
1011
|
-
"[testing-env/0] session 'session1' started",
|
|
1012
|
-
'[testing-env/0/session1] shell: echo foo with ValueError',
|
|
1013
|
-
'[testing-env/0/session1] shell: echo bar',
|
|
1014
|
-
'[testing-env/0] in_session -> exiting_session',
|
|
1015
|
-
'[testing-env/0/session1] shell: "feature1" teardown session',
|
|
1016
|
-
'[testing-env/0/feature1] feature teardown session',
|
|
1017
|
-
"[testing-env/0] session 'session1' ended",
|
|
1018
|
-
'[testing-env/0] exiting_session -> setting_up',
|
|
1019
|
-
'[testing-env/0] shell: "feature1" setup session',
|
|
1020
|
-
'[testing-env/0/feature1] feature setup session',
|
|
1021
|
-
'[testing-env/0] setting_up -> ready',
|
|
1010
|
+
'[testing-env/0:0] ready -> acquired',
|
|
1011
|
+
'[testing-env/0:0] acquired -> setting_up',
|
|
1012
|
+
'[testing-env/0:0] setting_up -> in_session',
|
|
1013
|
+
"[testing-env/0:0] session 'session1' started",
|
|
1014
|
+
'[testing-env/0:0/session1] shell: echo foo with ValueError',
|
|
1015
|
+
'[testing-env/0:0/session1] shell: echo bar',
|
|
1016
|
+
'[testing-env/0:0] in_session -> exiting_session',
|
|
1017
|
+
'[testing-env/0:0/session1] shell: "feature1" teardown session',
|
|
1018
|
+
'[testing-env/0:0/feature1] feature teardown session',
|
|
1019
|
+
"[testing-env/0:0] session 'session1' ended",
|
|
1020
|
+
'[testing-env/0:0] exiting_session -> setting_up',
|
|
1021
|
+
'[testing-env/0:0] shell: "feature1" setup session',
|
|
1022
|
+
'[testing-env/0:0/feature1] feature setup session',
|
|
1023
|
+
'[testing-env/0:0] setting_up -> ready',
|
|
1022
1024
|
]
|
|
1023
1025
|
)
|
|
1024
1026
|
|
|
@@ -1039,29 +1041,31 @@ class SandboxStatusTests(unittest.TestCase):
|
|
|
1039
1041
|
self.assertEqual(
|
|
1040
1042
|
self.event_handler.logs,
|
|
1041
1043
|
[
|
|
1042
|
-
|
|
1043
|
-
'[testing-env/0
|
|
1044
|
-
'[testing-env/0]
|
|
1045
|
-
'[testing-env/0
|
|
1046
|
-
'[testing-env/0]
|
|
1047
|
-
'[testing-env/0]
|
|
1044
|
+
# pylint: disable=line-too-long
|
|
1045
|
+
'[testing-env/0:0] shell: "feature1" setup',
|
|
1046
|
+
'[testing-env/0:0/feature1] feature setup',
|
|
1047
|
+
'[testing-env/0:0] shell: "feature1" setup session',
|
|
1048
|
+
'[testing-env/0:0/feature1] feature setup session',
|
|
1049
|
+
'[testing-env/0:0] created -> ready',
|
|
1050
|
+
'[testing-env/0:0] sandbox started',
|
|
1048
1051
|
'[testing-env] environment started',
|
|
1049
|
-
'[testing-env/0] ready -> acquired',
|
|
1050
|
-
'[testing-env/0] acquired -> setting_up',
|
|
1051
|
-
'[testing-env/0] setting_up -> in_session',
|
|
1052
|
-
"[testing-env/0] session 'session1' started",
|
|
1053
|
-
'[testing-env/0/session1] shell: echo foo with RuntimeError',
|
|
1054
|
-
'[testing-env/0] in_session -> exiting_session',
|
|
1055
|
-
'[testing-env/0/session1] shell: "feature1" teardown session',
|
|
1056
|
-
'[testing-env/0/feature1] feature teardown session',
|
|
1057
|
-
"[testing-env/0] session 'session1' ended with SandboxStateError",
|
|
1058
|
-
'[testing-env/0] exiting_session -> acquired',
|
|
1059
|
-
'[testing-env/0] acquired -> shutting_down',
|
|
1060
|
-
'[testing-env/0] shell: "feature1" teardown',
|
|
1061
|
-
'[testing-env/0/feature1] feature teardown',
|
|
1062
|
-
'[testing-env/0] shutting_down -> offline',
|
|
1063
|
-
'[testing-env/0] sandbox shutdown',
|
|
1064
|
-
'[testing-env/0] shell: echo bar',
|
|
1052
|
+
'[testing-env/0:0] ready -> acquired',
|
|
1053
|
+
'[testing-env/0:0] acquired -> setting_up',
|
|
1054
|
+
'[testing-env/0:0] setting_up -> in_session',
|
|
1055
|
+
"[testing-env/0:0] session 'session1' started",
|
|
1056
|
+
'[testing-env/0:0/session1] shell: echo foo with RuntimeError',
|
|
1057
|
+
'[testing-env/0:0] in_session -> exiting_session',
|
|
1058
|
+
'[testing-env/0:0/session1] shell: "feature1" teardown session',
|
|
1059
|
+
'[testing-env/0:0/feature1] feature teardown session',
|
|
1060
|
+
"[testing-env/0:0] session 'session1' ended with SandboxStateError",
|
|
1061
|
+
'[testing-env/0:0] exiting_session -> acquired',
|
|
1062
|
+
'[testing-env/0:0] acquired -> shutting_down',
|
|
1063
|
+
'[testing-env/0:0] shell: "feature1" teardown',
|
|
1064
|
+
'[testing-env/0:0/feature1] feature teardown',
|
|
1065
|
+
'[testing-env/0:0] shutting_down -> offline',
|
|
1066
|
+
'[testing-env/0:0] sandbox shutdown',
|
|
1067
|
+
'[testing-env/0:0] shell: echo bar',
|
|
1068
|
+
# pylint: enable=line-too-long
|
|
1065
1069
|
]
|
|
1066
1070
|
)
|
|
1067
1071
|
|
|
@@ -1107,12 +1111,15 @@ class SandboxActivityTests(unittest.TestCase):
|
|
|
1107
1111
|
self.assertEqual(sb.status, sb.Status.OFFLINE)
|
|
1108
1112
|
|
|
1109
1113
|
def test_housekeep_error(self):
|
|
1114
|
+
event_handler = TestingEventHandler(log_housekeep=False)
|
|
1110
1115
|
env = TestingEnvironment(
|
|
1111
1116
|
features={'test_feature': TestingFeature(housekeep_interval=0)},
|
|
1112
1117
|
pool_size=1,
|
|
1118
|
+
housekeep_interval=1.0,
|
|
1113
1119
|
outage_grace_period=0,
|
|
1114
|
-
outage_retry_interval=0,
|
|
1120
|
+
outage_retry_interval=0.1,
|
|
1115
1121
|
sandbox_keepalive_interval=0,
|
|
1122
|
+
event_handlers=[event_handler],
|
|
1116
1123
|
)
|
|
1117
1124
|
with env:
|
|
1118
1125
|
with env.sandbox('session1') as sb:
|
|
@@ -1129,6 +1136,31 @@ class SandboxActivityTests(unittest.TestCase):
|
|
|
1129
1136
|
):
|
|
1130
1137
|
time.sleep(0.01)
|
|
1131
1138
|
self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
|
|
1139
|
+
env.wait_for_housekeeping()
|
|
1140
|
+
self.assertEqual(
|
|
1141
|
+
event_handler.logs,
|
|
1142
|
+
[
|
|
1143
|
+
'[testing-env/0:0] shell: "test_feature" setup',
|
|
1144
|
+
'[testing-env/0:0/test_feature] feature setup',
|
|
1145
|
+
'[testing-env/0:0] shell: "test_feature" setup session',
|
|
1146
|
+
'[testing-env/0:0] sandbox started',
|
|
1147
|
+
'[testing-env] environment started',
|
|
1148
|
+
"[testing-env/0:0] session 'session1' started",
|
|
1149
|
+
'[testing-env/0:0/session1] shell: "test_feature" teardown session',
|
|
1150
|
+
"[testing-env/0:0] session 'session1' ended with SandboxStateError",
|
|
1151
|
+
'[testing-env/0:0] shell: "test_feature" teardown',
|
|
1152
|
+
'[testing-env/0:0/test_feature] feature teardown',
|
|
1153
|
+
'[testing-env/0:0] sandbox shutdown',
|
|
1154
|
+
'[testing-env/0:1] shell: "test_feature" setup',
|
|
1155
|
+
'[testing-env/0:1/test_feature] feature setup',
|
|
1156
|
+
'[testing-env/0:1] shell: "test_feature" setup session',
|
|
1157
|
+
'[testing-env/0:1] sandbox started',
|
|
1158
|
+
'[testing-env/0:1] shell: "test_feature" teardown',
|
|
1159
|
+
'[testing-env/0:1/test_feature] feature teardown',
|
|
1160
|
+
'[testing-env/0:1] sandbox shutdown',
|
|
1161
|
+
'[testing-env] environment shutdown'
|
|
1162
|
+
]
|
|
1163
|
+
)
|
|
1132
1164
|
|
|
1133
1165
|
def test_remove_event_handler(self):
|
|
1134
1166
|
env = TestingEnvironment(
|
|
@@ -8,5 +8,7 @@ from langfun.env.event_handlers.base import EventHandler
|
|
|
8
8
|
from langfun.env.event_handlers.event_logger import EventLogger
|
|
9
9
|
from langfun.env.event_handlers.event_logger import ConsoleEventLogger
|
|
10
10
|
|
|
11
|
+
from langfun.env.event_handlers.metric_writer import MetricWriter
|
|
12
|
+
|
|
11
13
|
# pylint: enable=g-importing-member
|
|
12
14
|
# pylint: enable=g-bad-import-order
|
|
@@ -48,6 +48,7 @@ class _SessionEventHandler:
|
|
|
48
48
|
environment: Environment,
|
|
49
49
|
sandbox: Sandbox,
|
|
50
50
|
session_id: str,
|
|
51
|
+
duration: float,
|
|
51
52
|
lifetime: float,
|
|
52
53
|
error: BaseException | None
|
|
53
54
|
) -> None:
|
|
@@ -57,6 +58,7 @@ class _SessionEventHandler:
|
|
|
57
58
|
environment: The environment.
|
|
58
59
|
sandbox: The sandbox.
|
|
59
60
|
session_id: The session ID.
|
|
61
|
+
duration: The time spent on ending the session.
|
|
60
62
|
lifetime: The session lifetime in seconds.
|
|
61
63
|
error: The error that caused the session to end. If None, the session
|
|
62
64
|
ended normally.
|
|
@@ -162,6 +164,7 @@ class _SandboxEventHandler(_FeatureEventHandler, _SessionEventHandler):
|
|
|
162
164
|
self,
|
|
163
165
|
environment: Environment,
|
|
164
166
|
sandbox: Sandbox,
|
|
167
|
+
duration: float,
|
|
165
168
|
lifetime: float,
|
|
166
169
|
error: BaseException | None
|
|
167
170
|
) -> None:
|
|
@@ -170,6 +173,7 @@ class _SandboxEventHandler(_FeatureEventHandler, _SessionEventHandler):
|
|
|
170
173
|
Args:
|
|
171
174
|
environment: The environment.
|
|
172
175
|
sandbox: The sandbox.
|
|
176
|
+
duration: The time spent on shutting down the sandbox.
|
|
173
177
|
lifetime: The sandbox lifetime in seconds.
|
|
174
178
|
error: The error that caused the sandbox to shutdown. If None, the
|
|
175
179
|
sandbox shutdown normally.
|
|
@@ -223,6 +227,13 @@ class _SandboxEventHandler(_FeatureEventHandler, _SessionEventHandler):
|
|
|
223
227
|
class EventHandler(_SandboxEventHandler):
|
|
224
228
|
"""Base class for event handlers of an environment."""
|
|
225
229
|
|
|
230
|
+
def on_environment_starting(self, environment: Environment) -> None:
|
|
231
|
+
"""Called when the environment is getting started.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
environment: The environment.
|
|
235
|
+
"""
|
|
236
|
+
|
|
226
237
|
def on_environment_start(
|
|
227
238
|
self,
|
|
228
239
|
environment: Environment,
|
|
@@ -258,6 +269,7 @@ class EventHandler(_SandboxEventHandler):
|
|
|
258
269
|
def on_environment_shutdown(
|
|
259
270
|
self,
|
|
260
271
|
environment: Environment,
|
|
272
|
+
duration: float,
|
|
261
273
|
lifetime: float,
|
|
262
274
|
error: BaseException | None
|
|
263
275
|
) -> None:
|
|
@@ -265,6 +277,7 @@ class EventHandler(_SandboxEventHandler):
|
|
|
265
277
|
|
|
266
278
|
Args:
|
|
267
279
|
environment: The environment.
|
|
280
|
+
duration: The environment shutdown duration in seconds.
|
|
268
281
|
lifetime: The environment lifetime in seconds.
|
|
269
282
|
error: The error that caused the environment to shutdown. If None, the
|
|
270
283
|
environment shutdown normally.
|