|
46 | 46 | YAMLParseError,
|
47 | 47 | )
|
48 | 48 | from readthedocs.storage import build_media_storage
|
| 49 | +from readthedocs.telemetry.collectors import BuildDataCollector |
| 50 | +from readthedocs.telemetry.tasks import save_build_data |
49 | 51 | from readthedocs.worker import app
|
50 | 52 |
|
51 | 53 | from ..exceptions import (
|
@@ -346,6 +348,8 @@ def before_start(self, task_id, args, kwargs):
|
346 | 348 | # Reset any previous build error reported to the user
|
347 | 349 | self.data.build['error'] = ''
|
348 | 350 |
|
| 351 | + self.data.build_data = None |
| 352 | + |
349 | 353 | # Also note there are builds that are triggered without a commit
|
350 | 354 | # because they just build the latest commit for that version
|
351 | 355 | self.data.build_commit = kwargs.get('build_commit')
|
@@ -540,6 +544,7 @@ def after_return(self, status, retval, task_id, args, kwargs, einfo):
|
540 | 544 | self.data.build['length'] = (timezone.now() - self.data.start_time).seconds
|
541 | 545 |
|
542 | 546 | self.update_build(BUILD_STATE_FINISHED)
|
| 547 | + self.save_build_data() |
543 | 548 |
|
544 | 549 | build_complete.send(sender=Build, build=self.data.build)
|
545 | 550 |
|
@@ -595,13 +600,46 @@ def execute(self):
|
595 | 600 | # ``__exit__``
|
596 | 601 | self.data.build_director.create_build_environment()
|
597 | 602 | with self.data.build_director.build_environment:
|
598 |
| - # Installing |
599 |
| - self.update_build(state=BUILD_STATE_INSTALLING) |
600 |
| - self.data.build_director.setup_environment() |
| 603 | + try: |
| 604 | + # Installing |
| 605 | + self.update_build(state=BUILD_STATE_INSTALLING) |
| 606 | + self.data.build_director.setup_environment() |
| 607 | + |
| 608 | + # Building |
| 609 | + self.update_build(state=BUILD_STATE_BUILDING) |
| 610 | + self.data.build_director.build() |
| 611 | + finally: |
| 612 | + self.data.build_data = self.collect_build_data() |
| 613 | + |
| 614 | + def collect_build_data(self): |
| 615 | + """ |
| 616 | + Collect data from the current build. |
601 | 617 |
|
602 |
| - # Building |
603 |
| - self.update_build(state=BUILD_STATE_BUILDING) |
604 |
| - self.data.build_director.build() |
| 618 | + The data is collected from inside the container, |
| 619 | + so this must be called before killing the container. |
| 620 | + """ |
| 621 | + try: |
| 622 | + return BuildDataCollector( |
| 623 | + self.data.build_director.build_environment |
| 624 | + ).collect() |
| 625 | + except Exception: |
| 626 | + log.exception("Error while collecting build data") |
| 627 | + |
| 628 | + def save_build_data(self): |
| 629 | + """ |
| 630 | + Save the data collected from the build after it has ended. |
| 631 | +
|
| 632 | + This must be called after the build has finished updating its state, |
| 633 | + otherwise some attributes like ``length`` won't be available. |
| 634 | + """ |
| 635 | + try: |
| 636 | + if self.data.build_data: |
| 637 | + save_build_data.delay( |
| 638 | + build_id=self.data.build_pk, |
| 639 | + data=self.data.build_data, |
| 640 | + ) |
| 641 | + except Exception: |
| 642 | + log.exception("Error while saving build data") |
605 | 643 |
|
606 | 644 | @staticmethod
|
607 | 645 | def get_project(project_pk):
|
|
0 commit comments