def check_repeaters(): start = datetime.utcnow() six_hours_sec = 6 * 60 * 60 six_hours_later = start + timedelta(seconds=six_hours_sec) # Long timeout to allow all waiting repeat records to be iterated check_repeater_lock = get_redis_lock( CHECK_REPEATERS_KEY, timeout=six_hours_sec, name=CHECK_REPEATERS_KEY, ) if not check_repeater_lock.acquire(blocking=False): metrics_counter("commcare.repeaters.check.locked_out") return try: with datadog_bucket_timer( "commcare.repeaters.check.processing", tags=[], timing_buckets=_check_repeaters_buckets, ): for record in iterate_repeat_records(start): if datetime.utcnow() > six_hours_later: _soft_assert( False, "I've been iterating repeat records for six hours. I quit!" ) break metrics_counter("commcare.repeaters.check.attempt_forward") record.attempt_forward_now() finally: check_repeater_lock.release()
def save_copy(request, domain, app_id): """ Saves a copy of the app to a new doc. See ApplicationBase.save_copy """ track_built_app_on_hubspot.delay(request.couch_user) comment = request.POST.get('comment') app = get_app(domain, app_id) try: errors = app.validate_app() except ModuleIdMissingException: # For apps (mainly Exchange apps) that lost unique_id attributes on Module app.ensure_module_unique_ids(should_save=True) errors = app.validate_app() if not errors: try: user_id = request.couch_user.get_id timer = datadog_bucket_timer('commcare.app_build.new_release', tags=[], timing_buckets=(1, 10, 30, 60, 120, 240)) with timer: copy = make_app_build(app, comment, user_id) CouchUser.get(user_id).set_has_built_app() except BuildConflictException: return JsonResponse( { 'error': _("There is already a version build in progress. Please wait." ) }, status=400) finally: # To make a RemoteApp always available for building if app.is_remote_app(): app.save(increment_version=True) _track_build_for_app_preview(domain, request.couch_user, app_id, 'User created a build') else: copy = None copy = copy and SavedAppBuild.wrap(copy.to_json()).releases_list_json( get_timezone_for_user(request.couch_user, domain)) lang, langs = get_langs(request, app) return json_response({ "saved_app": copy, "error_html": render_to_string( "app_manager/partials/build_errors.html", { 'app': get_app(domain, app_id), 'build_errors': errors, 'domain': domain, 'langs': langs, }), })
def check_repeaters(): start = datetime.utcnow() six_hours_sec = 6 * 60 * 60 six_hours_later = start + timedelta(seconds=six_hours_sec) # Long timeout to allow all waiting repeat records to be iterated check_repeater_lock = get_redis_lock( CHECK_REPEATERS_KEY, timeout=six_hours_sec, name=CHECK_REPEATERS_KEY, ) if not check_repeater_lock.acquire(blocking=False): datadog_counter("commcare.repeaters.check.locked_out") return try: with datadog_bucket_timer( "commcare.repeaters.check.processing", tags=[], timing_buckets=_check_repeaters_buckets, ): for record in iterate_repeat_records(start): if datetime.utcnow() > six_hours_later: _soft_assert(False, "I've been iterating repeat records for six hours. I quit!") break datadog_counter("commcare.repeaters.check.attempt_forward") record.attempt_forward_now() finally: check_repeater_lock.release()
def es_results(self): timer = datadog_bucket_timer( 'commcare.case_list_explorer_query.es_timings', tags=[], timing_buckets=(0.01, 0.05, 1, 5), ) with timer: return super(CaseListExplorer, self).es_results
def _datadog_timing(self, step): return datadog_bucket_timer('commcare.change_feed.processor.timing', tags=[ 'action:{}'.format(step), 'index:{}'.format( self.index_info.alias), ], timing_buckets=(.03, .1, .3, 1, 3, 10))
def direct_ccz(request, domain): """ You must specify an app_id, and you may specify either 'version' or 'latest' latest can be one of: release: Latest starred version build: Latest version regardless of star save: Latest saved version of the application (even without a build) If 'version' and 'latest' aren't specified it will default to latest save You may also set 'include_multimedia=true' if you need multimedia. """ def error(msg, code=400): return json_response({'status': 'error', 'message': msg}, status_code=code) def get_app(app_id, version, latest): if version: return get_build_doc_by_version(domain, app_id, version) elif latest == 'build': return get_latest_build_doc(domain, app_id) elif latest == 'release': return get_latest_released_app_doc(domain, app_id) else: # either latest=='save' or they didn't specify return get_current_app(domain, app_id) app_id = request.GET.get('app_id', None) version = request.GET.get('version', None) latest = request.GET.get('latest', None) include_multimedia = request.GET.get('include_multimedia', 'false').lower() == 'true' visit_scheduler_enabled = toggles.VISIT_SCHEDULER.enabled_for_request(request) # Make sure URL params make sense if not app_id: return error("You must specify `app_id` in your GET parameters") if version and latest: return error("You can't specify both 'version' and 'latest'") if latest not in (None, 'release', 'build', 'save',): return error("latest must be either 'release', 'build', or 'save'") if version: try: version = int(version) except ValueError: return error("'version' must be an integer") try: app = get_app(app_id, version, latest) if not app: raise ResourceNotFound() app = app if isinstance(app, Document) else wrap_app(app) except (ResourceNotFound, DocTypeError): return error("Application not found", code=404) lang, langs = get_langs(request, app) timer = datadog_bucket_timer('commcare.app_build.live_preview', tags=[], timing_buckets=(1, 10, 30, 60, 120, 240)) with timer: return get_direct_ccz(domain, app, lang, langs, version, include_multimedia, visit_scheduler_enabled)
def save_copy(request, domain, app_id): """ Saves a copy of the app to a new doc. See VersionedDoc.save_copy """ track_built_app_on_hubspot_v2.delay(request.couch_user) comment = request.POST.get('comment') app = get_app(domain, app_id) try: errors = app.validate_app() except ModuleIdMissingException: # For apps (mainly Exchange apps) that lost unique_id attributes on Module app.ensure_module_unique_ids(should_save=True) errors = app.validate_app() if not errors: try: user_id = request.couch_user.get_id timer = datadog_bucket_timer('commcare.app_build.new_release', tags=[], timing_buckets=(1, 10, 30, 60, 120, 240)) with timer: copy = app.make_build( comment=comment, user_id=user_id, ) copy.save(increment_version=False) CouchUser.get(user_id).set_has_built_app() finally: # To make a RemoteApp always available for building if app.is_remote_app(): app.save(increment_version=True) _track_build_for_app_preview(domain, request.couch_user, app_id, 'User created a build') else: copy = None copy = copy and SavedAppBuild.wrap(copy.to_json()).releases_list_json( get_timezone_for_user(request.couch_user, domain) ) lang, langs = get_langs(request, app) if copy: # Set if build is supported for Java Phones j2me_enabled_configs = CommCareBuildConfig.j2me_enabled_config_labels() copy['j2me_enabled'] = copy['menu_item_label'] in j2me_enabled_configs return json_response({ "saved_app": copy, "error_html": render_to_string("app_manager/partials/build_errors.html", { 'request': request, 'app': get_app(domain, app_id), 'build_errors': errors, 'domain': domain, 'langs': langs, 'lang': lang }), })
def _datadog_timing(self, step, config_id=None): tags = [ 'action:{}'.format(step), 'index:ucr', ] if config_id and settings.ENTERPRISE_MODE: tags.append('config_id:{}'.format(config_id)) return datadog_bucket_timer('commcare.change_feed.processor.timing', tags=tags, timing_buckets=(.03, .1, .3, 1, 3, 10))
def __init__(self, lock, name, track_unreleased=True): self.lock = lock self.tags = ["lock_name:%s" % name] self.name = name self.key = lock.name self.lock_timer = datadog_bucket_timer( "commcare.lock.locked_time", self.tags, self.timing_buckets) self.track_unreleased = track_unreleased self.end_time = None self.lock_trace = None
def __init__(self, lock, name, track_unreleased=True): self.lock = lock self.tags = ["lock_name:%s" % name] self.name = name self.key = lock.name self.lock_timer = datadog_bucket_timer("commcare.lock.locked_time", self.tags, self.timing_buckets) self.track_unreleased = track_unreleased self.end_time = None self.lock_trace = None
def _get_rows(self, data): timer = datadog_bucket_timer( 'commcare.case_list_explorer_query.row_fetch_timings', tags=[], timing_buckets=(0.01, 0.05, 1, 5), ) with timer: for case in data: case_display = SafeCaseDisplay(self, case) yield [ case_display.get(column.prop_name) for column in self.columns ]
def report_timing(self, action, key): def record_long_request(duration): if duration > 100: notify_exception(None, "S3BlobDB request took a long time.", details={ 'duration': duration, 's3_bucket_name': self.s3_bucket_name, 'action': action, 'key': key, }) return datadog_bucket_timer('commcare.blobs.requests.timing', tags=[ 'action:{}'.format(action), 's3_bucket_name:{}'.format(self.s3_bucket_name) ], timing_buckets=(.03, .1, .3, 1, 3, 10, 30, 100), callback=record_long_request)
def acquire(self, *args, **kw): tags = self.tags buckets = self.timing_buckets with datadog_bucket_timer("commcare.lock.acquire_time", tags, buckets), \ tracer.trace("commcare.lock.acquire", resource=self.key) as span: acquired = self.lock.acquire(*args, **kw) span.set_tags({ "key": self.key, "name": self.name, "acquired": ("true" if acquired else "false"), }) if acquired: timeout = getattr(self.lock, "timeout", None) if timeout: self.end_time = time.time() + timeout self.lock_timer.start() if self.track_unreleased: self.lock_trace = tracer.trace("commcare.lock.locked", resource=self.key) self.lock_trace.set_tags({"key": self.key, "name": self.name}) return acquired
def direct_ccz(request, domain): """ You must specify an app_id, and you may specify either 'version' or 'latest' latest can be one of: release: Latest starred version build: Latest version regardless of star save: Latest saved version of the application (even without a build) If 'version' and 'latest' aren't specified it will default to latest save You may also set 'include_multimedia=true' if you need multimedia. """ def error(msg, code=400): return json_response({ 'status': 'error', 'message': msg }, status_code=code) def get_app(app_id, version, latest): if version: return get_build_doc_by_version(domain, app_id, version) elif latest == 'build': return get_latest_build_doc(domain, app_id) elif latest == 'release': return get_latest_released_app_doc(domain, app_id) else: # either latest=='save' or they didn't specify return get_current_app(domain, app_id) app_id = request.GET.get('app_id', None) version = request.GET.get('version', None) latest = request.GET.get('latest', None) include_multimedia = request.GET.get('include_multimedia', 'false').lower() == 'true' visit_scheduler_enabled = toggles.VISIT_SCHEDULER.enabled_for_request( request) # Make sure URL params make sense if not app_id: return error("You must specify `app_id` in your GET parameters") if version and latest: return error("You can't specify both 'version' and 'latest'") if latest not in ( None, 'release', 'build', 'save', ): return error("latest must be either 'release', 'build', or 'save'") if version: try: version = int(version) except ValueError: return error("'version' must be an integer") try: app = get_app(app_id, version, latest) if not app: raise ResourceNotFound() app = app if isinstance(app, Document) else wrap_app(app) except (ResourceNotFound, DocTypeError): return error("Application not found", code=404) lang, langs = get_langs(request, app) timer = datadog_bucket_timer('commcare.app_build.live_preview', tags=[], timing_buckets=(1, 10, 30, 60, 120, 240)) with timer: return get_direct_ccz(domain, app, lang, langs, version, include_multimedia, visit_scheduler_enabled)