Esempio n. 1
0
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()
Esempio n. 2
0
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,
            }),
    })
Esempio n. 3
0
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()
Esempio n. 4
0
 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 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
Esempio n. 6
0
 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))
Esempio n. 7
0
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)
Esempio n. 8
0
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
        }),
    })
Esempio n. 9
0
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
        }),
    })
Esempio n. 10
0
 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))
Esempio n. 11
0
 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
Esempio n. 12
0
 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
Esempio n. 13
0
 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 _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
             ]
Esempio n. 15
0
    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)
Esempio n. 16
0
    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)
Esempio n. 17
0
 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
Esempio n. 18
0
 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
Esempio n. 19
0
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)