diff --git a/awx/conf/settings.py b/awx/conf/settings.py index 98a39978d3..d2733ce879 100644 --- a/awx/conf/settings.py +++ b/awx/conf/settings.py @@ -17,6 +17,8 @@ from django.utils.functional import cached_property # Django REST Framework from rest_framework.fields import empty, SkipField +import cachetools + # Tower from awx.main.utils import encrypt_field, decrypt_field from awx.conf import settings_registry @@ -28,6 +30,8 @@ from awx.conf.migrations._reencrypt import decrypt_field as old_decrypt_field logger = logging.getLogger('awx.conf.settings') +SETTING_MEMORY_TTL = 5 if 'callback_receiver' in ' '.join(sys.argv) else 0 + # Store a special value to indicate when a setting is not set in the database. SETTING_CACHE_NOTSET = '___notset___' @@ -406,6 +410,7 @@ class SettingsWrapper(UserSettingsHolder): def SETTINGS_MODULE(self): return self._get_default('SETTINGS_MODULE') + @cachetools.cached(cache=cachetools.TTLCache(maxsize=2048, ttl=SETTING_MEMORY_TTL)) def __getattr__(self, name): value = empty if name in self.all_supported_settings: diff --git a/awx/main/models/events.py b/awx/main/models/events.py index 1f79b0e24b..09ccb07125 100644 --- a/awx/main/models/events.py +++ b/awx/main/models/events.py @@ -4,6 +4,7 @@ import datetime import logging from collections import defaultdict +from django.conf import settings from django.db import models, DatabaseError, connection from django.utils.dateparse import parse_datetime from django.utils.text import Truncator @@ -57,7 +58,18 @@ def create_host_status_counts(event_data): return dict(host_status_counts) +MINIMAL_EVENTS = set([ + 'playbook_on_play_start', 'playbook_on_task_start', + 'playbook_on_stats', 'EOF' +]) + + def emit_event_detail(event): + if ( + settings.UI_LIVE_UPDATES_ENABLED is False and + event.event not in MINIMAL_EVENTS + ): + return cls = event.__class__ relation = { JobEvent: 'job_id', @@ -368,10 +380,11 @@ class BasePlaybookEvent(CreatedModifiedModel): value = force_text(event_data.get(field, '')).strip() if value != getattr(self, field): setattr(self, field, value) - analytics_logger.info( - 'Event data saved.', - extra=dict(python_objects=dict(job_event=self)) - ) + if settings.LOG_AGGREGATOR_ENABLED: + analytics_logger.info( + 'Event data saved.', + extra=dict(python_objects=dict(job_event=self)) + ) @classmethod def create_from_data(cls, **kwargs): diff --git a/awx/ui/client/features/output/stream.service.js b/awx/ui/client/features/output/stream.service.js index 11198e0752..c3cfa10622 100644 --- a/awx/ui/client/features/output/stream.service.js +++ b/awx/ui/client/features/output/stream.service.js @@ -119,6 +119,10 @@ function OutputStream ($q) { this.counters.ready = ready; this.counters.used = used; this.counters.missing = missing; + + if (!window.liveUpdates) { + this.counters.ready = event.counter; + } }; this.bufferEmpty = threshold => { @@ -141,6 +145,10 @@ function OutputStream ($q) { const { total } = this.counters; const readyCount = this.getReadyCount(); + if (!window.liveUpdates) { + return true; + } + if (readyCount <= 0) { return false; } diff --git a/awx/ui/test/unit/components/stream.unit.js b/awx/ui/test/unit/components/stream.unit.js index c4343d59b7..5d979592be 100644 --- a/awx/ui/test/unit/components/stream.unit.js +++ b/awx/ui/test/unit/components/stream.unit.js @@ -51,7 +51,13 @@ describe('Output | StreamService', () => { }); describe('isReadyToRender', () => { - it("it's never ready to render unless the result of getReadyCount is greater than 0", () => { + it("it's never ready to render when live updates are enabled unless the result of getReadyCount is greater than 0", () => { + delete window.liveUpdates; + Object.defineProperty(window, 'liveUpdates', { + value: true, + writable: false + }); + const params = [ [-1, false], [0, false],