diff --git a/awx/main/management/commands/run_callback_receiver.py b/awx/main/management/commands/run_callback_receiver.py index 42db7416b0..0c6c4f90dd 100644 --- a/awx/main/management/commands/run_callback_receiver.py +++ b/awx/main/management/commands/run_callback_receiver.py @@ -25,6 +25,7 @@ from django.core.cache import cache as django_cache # AWX from awx.main.models import * # noqa +from awx.main.consumers import emit_channel_notification logger = logging.getLogger('awx.main.commands.run_callback_receiver') @@ -159,6 +160,17 @@ class CallbackBrokerWorker(ConsumerMixin): job_identifier = body[key] break + if body.get('event') == 'EOF': + # EOF events are sent when stdout for the running task is + # closed. don't actually persist them to the database; we + # just use them to report `summary` websocket events as an + # approximation for when a job is "done" + emit_channel_notification( + 'jobs-summary', + dict(group_name='jobs', unified_job_id=job_identifier) + ) + continue + retries = 0 while retries <= self.MAX_RETRIES: try: diff --git a/awx/main/models/events.py b/awx/main/models/events.py index e864c10caf..66e4b599ee 100644 --- a/awx/main/models/events.py +++ b/awx/main/models/events.py @@ -9,7 +9,6 @@ from django.utils.translation import ugettext_lazy as _ from django.utils.encoding import force_text from awx.api.versioning import reverse -from awx.main.consumers import emit_channel_notification from awx.main.fields import JSONField from awx.main.models.base import CreatedModifiedModel from awx.main.utils import ignore_inventory_computed_fields @@ -361,8 +360,6 @@ class BasePlaybookEvent(CreatedModifiedModel): self._update_host_summary_from_stats(hostnames) self.job.inventory.update_computed_fields() - emit_channel_notification('jobs-summary', dict(group_name='jobs', unified_job_id=self.job.id)) - class JobEvent(BasePlaybookEvent): diff --git a/awx/main/utils/common.py b/awx/main/utils/common.py index 3c38ec4b0f..43e88875b7 100644 --- a/awx/main/utils/common.py +++ b/awx/main/utils/common.py @@ -878,8 +878,10 @@ class OutputEventFilter(object): if self._buffer: self._emit_event(self._buffer) self._buffer = '' + self._event_callback(dict(event='EOF')) def _emit_event(self, buffered_stdout, next_event_data=None): + next_event_data = next_event_data or {} if self._current_event_data: event_data = self._current_event_data stdout_chunks = [buffered_stdout] diff --git a/awx/ui/client/src/shared/socket/socket.service.js b/awx/ui/client/src/shared/socket/socket.service.js index 8157fc4477..7c390d0cba 100644 --- a/awx/ui/client/src/shared/socket/socket.service.js +++ b/awx/ui/client/src/shared/socket/socket.service.js @@ -216,15 +216,14 @@ export default self.unsubscribe(state); } else{ - if(state.data && state.data.socket && state.data.socket.groups.hasOwnProperty( "job_events")){ - state.data.socket.groups.job_events = [id]; - } - if(state.data && state.data.socket && state.data.socket.groups.hasOwnProperty( "ad_hoc_command_events")){ - state.data.socket.groups.ad_hoc_command_events = [id]; - } - if(state.data && state.data.socket && state.data.socket.groups.hasOwnProperty( "workflow_events")){ - state.data.socket.groups.workflow_events = [id]; - } + ["job_events", "ad_hoc_command_events", "workflow_events", + "project_update_events", "inventory_update_events", + "system_job_events" + ].forEach(function(group) { + if(state.data && state.data.socket && state.data.socket.groups.hasOwnProperty(group)){ + state.data.socket.groups[group] = [id]; + } + }); self.subscribe(state); } return true; diff --git a/awx/ui/client/src/standard-out/adhoc/standard-out-adhoc.route.js b/awx/ui/client/src/standard-out/adhoc/standard-out-adhoc.route.js index e9510deb62..e294116d78 100644 --- a/awx/ui/client/src/standard-out/adhoc/standard-out-adhoc.route.js +++ b/awx/ui/client/src/standard-out/adhoc/standard-out-adhoc.route.js @@ -19,7 +19,7 @@ export default { jobType: 'ad_hoc_commands', socket: { "groups": { - "jobs": ["status_changed"], + "jobs": ["status_changed", "summary"], "ad_hoc_command_events": [] } } diff --git a/awx/ui/client/src/standard-out/inventory-sync/standard-out-inventory-sync.route.js b/awx/ui/client/src/standard-out/inventory-sync/standard-out-inventory-sync.route.js index 942d435bb0..b3931d345c 100644 --- a/awx/ui/client/src/standard-out/inventory-sync/standard-out-inventory-sync.route.js +++ b/awx/ui/client/src/standard-out/inventory-sync/standard-out-inventory-sync.route.js @@ -20,7 +20,8 @@ export default { data: { socket: { "groups":{ - "jobs": ["status_changed"] + "jobs": ["status_changed", "summary"], + "inventory_update_events": [], } }, jobType: 'inventory_updates' diff --git a/awx/ui/client/src/standard-out/management-jobs/standard-out-management-jobs.route.js b/awx/ui/client/src/standard-out/management-jobs/standard-out-management-jobs.route.js index 75472922b8..950801990c 100644 --- a/awx/ui/client/src/standard-out/management-jobs/standard-out-management-jobs.route.js +++ b/awx/ui/client/src/standard-out/management-jobs/standard-out-management-jobs.route.js @@ -19,7 +19,8 @@ export default { jobType: 'system_jobs', socket: { "groups": { - "jobs": ["status_changed"] + "jobs": ["status_changed", "summary"], + "system_job_events": [], } } } diff --git a/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.route.js b/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.route.js index 87d0942802..c2e43be9ca 100644 --- a/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.route.js +++ b/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.route.js @@ -21,7 +21,8 @@ export default { jobType: 'project_updates', socket: { "groups": { - "jobs": ["status_changed"] + "jobs": ["status_changed", "summary"], + "project_update_events": [], } }, }