def visit(self): """Record that the user has visited the site for the purposes of retention tracking""" for enrollment in self._get_all_enrollments(): if enrollment.experiment.is_displaying_alternatives(): # We have two different goals, VISIT_NOT_PRESENT_COUNT_GOAL and VISIT_PRESENT_COUNT_GOAL. # VISIT_PRESENT_COUNT_GOAL will avoid firing on the first time we set last_seen as it is assumed that the user is # on the page and therefore it would automatically trigger and be valueless. # This should be used for experiments when we enroll the user as part of the pageview, # alternatively we can use the NOT_PRESENT GOAL which will increment on the first pageview, # this is mainly useful for notification actions when the users isn't initially present. if not enrollment.last_seen: self._experiment_goal(enrollment.experiment, enrollment.alternative, conf.VISIT_NOT_PRESENT_COUNT_GOAL, 1) self._set_last_seen(enrollment.experiment, now()) elif now() - enrollment.last_seen >= timedelta( hours=conf.SESSION_LENGTH): self._experiment_goal(enrollment.experiment, enrollment.alternative, conf.VISIT_NOT_PRESENT_COUNT_GOAL, 1) self._experiment_goal(enrollment.experiment, enrollment.alternative, conf.VISIT_PRESENT_COUNT_GOAL, 1) self._set_last_seen(enrollment.experiment, now())
def visit(self): """Record that the user has visited the site for the purposes of retention tracking""" for enrollment in self._get_all_enrollments(): if enrollment.experiment.is_displaying_alternatives(): if not enrollment.last_seen or now() - enrollment.last_seen >= timedelta(1): self._experiment_goal(enrollment.experiment, enrollment.alternative, conf.VISIT_COUNT_GOAL, 1) self._set_last_seen(enrollment.experiment, now())
def _set_enrollment(self, experiment, alternative, enrollment_date=None, last_seen=None): enrollments = self.session.get('experiments_enrollments', {}) enrollments[experiment.name] = (alternative, None, timestamp_from_datetime(enrollment_date or now()), timestamp_from_datetime(last_seen)) self.session['experiments_enrollments'] = enrollments if self._is_verified_human(): self.experiment_counter.increment_participant_count( experiment, alternative, self._participant_identifier()) else: logger.info( json.dumps({ 'type': 'participant_unconfirmed', 'experiment': experiment.name, 'alternative': alternative, 'participant': self._participant_identifier() })) user_enrolled.send(self, experiment=experiment.name, alternative=alternative, user=None, session=self.session)
def state(self, request): if not request.user.has_perm('experiments.change_experiment'): raise ExperimentException("You do not have permission to do that!") experiment = Experiment.objects.get(name=request.POST.get("name")) try: state = int(request.POST.get("state")) except ValueError: raise ExperimentException("State must be integer") experiment.state = state if state == 0: experiment.end_date = now() else: experiment.end_date = None experiment.save() response = { "success": True, "experiment": experiment.to_dict_serialized(), } return response
def visit(self): """Record that the user has visited the site for the purposes of retention tracking""" for enrollment in self._get_all_enrollments(): if enrollment.experiment.is_displaying_alternatives(): # We have two different goals, VISIT_NOT_PRESENT_COUNT_GOAL and VISIT_PRESENT_COUNT_GOAL. # VISIT_PRESENT_COUNT_GOAL will avoid firing on the first time we set last_seen as it is assumed that the user is # on the page and therefore it would automatically trigger and be valueless. # This should be used for experiments when we enroll the user as part of the pageview, # alternatively we can use the NOT_PRESENT GOAL which will increment on the first pageview, # this is mainly useful for notification actions when the users isn't initially present. if not enrollment.last_seen: self._experiment_goal(enrollment.experiment, enrollment.alternative, conf.VISIT_NOT_PRESENT_COUNT_GOAL, 1) self._set_last_seen(enrollment.experiment, now()) elif now() - enrollment.last_seen >= timedelta(hours=conf.SESSION_LENGTH): self._experiment_goal(enrollment.experiment, enrollment.alternative, conf.VISIT_NOT_PRESENT_COUNT_GOAL, 1) self._experiment_goal(enrollment.experiment, enrollment.alternative, conf.VISIT_PRESENT_COUNT_GOAL, 1) self._set_last_seen(enrollment.experiment, now())
def extend(self, timeout=DEFAULT_TIMEOUT): """ Extend validity of the lock by <timeout> seconds. Non-blocking. """ if not self.locked(): return False self.expire_at = now() + timedelta(seconds=timeout) self.save() return True
def _set_enrollment(self, experiment, alternative, enrollment_date=None, last_seen=None): enrollments = self.session.get('experiments_enrollments', {}) enrollments[experiment.name] = (alternative, None, enrollment_date or now(), last_seen) self.session['experiments_enrollments'] = enrollments if self._is_verified_human(): experiment.increment_participant_count( alternative, self._participant_identifier())
def acquire(self, blocking=True, timeout=None): """ Acquire the lock. If acquired, lock will be auto-release after <timeout> seconds. If not acquired and <blocking>, will keep retrying every second for <timeout> seconds. """ if not blocking and timeout is not None: raise ValueError('Cannot set timeout if not blocking') timeout = self.DEFAULT_TIMEOUT if timeout is None else timeout if timeout < 0: raise ValueError('Cannot set negative timeout') if timeout > TIMEOUT_MAX: raise OverflowError('Timeout too large') self.cleanup() expire_at = now() + timedelta(seconds=timeout) acquired = self._acquire(blocking, expire_at) if acquired: self.expire_at = now() + timedelta(seconds=timeout) self.save() return acquired
def _acquire(self, blocking, expire_at): try: lock, acquired = DbLock.objects.get_or_create( name=self.name, defaults={'expire_at': expire_at}, ) except (IntegrityError, OperationalError): acquired = False lock = None if acquired: self.uuid = lock.uuid return True if not blocking: return False while not acquired and now() < expire_at: sleep(self.RETRY_INTERVAL * random.uniform(0.75, 1.25)) self.cleanup() acquired = self._acquire(False, expire_at) return acquired
def _set_enrollment(self, experiment, alternative, enrollment_date=None, last_seen=None): enrollments = self.session.get("experiments_enrollments", {}) enrollments[experiment.name] = ( alternative, None, timestamp_from_datetime(enrollment_date or now()), timestamp_from_datetime(last_seen), ) self.session["experiments_enrollments"] = enrollments if self._is_verified_human(): self.experiment_counter.increment_participant_count(experiment, alternative, self._participant_identifier()) else: logger.info( json.dumps( { "type": "participant_unconfirmed", "experiment": experiment.name, "alternative": alternative, "participant": self._participant_identifier(), } ) ) user_enrolled.send(self, experiment=experiment.name, alternative=alternative, user=None, session=self.session)
def _set_enrollment(self, experiment, alternative, enrollment_date=None, last_seen=None): enrollments = self.session.get('experiments_enrollments', {}) enrollments[experiment.name] = (alternative, None, enrollment_date or now(), last_seen) self.session['experiments_enrollments'] = enrollments if self._is_verified_human(): experiment.increment_participant_count(alternative, self._participant_identifier())
def cleanup(cls): """Delete expired locks.""" try: cls.objects.filter(expire_at__lte=now()).delete() except OperationalError: pass
def _set_enrollment(self, experiment, alternative, enrollment_date=None, last_seen=None): enrollments = self.session.get('experiments_enrollments', {}) enrollments[experiment.name] = (alternative, None, timestamp_from_datetime(enrollment_date or now()), timestamp_from_datetime(last_seen)) self.session['experiments_enrollments'] = enrollments if self._is_verified_human(): self.experiment_counter.increment_participant_count(experiment, alternative, self._participant_identifier()) else: logger.info(json.dumps({'type':'participant_unconfirmed', 'experiment': experiment.name, 'alternative': alternative, 'participant': self._participant_identifier()})) user_enrolled.send(self, experiment=experiment.name, alternative=alternative, user=None, session=self.session)
def _set_enrollment(self, experiment, alternative, enrollment_date=None, last_seen=None): enrollments = self.session.get('experiments_enrollments', {}) enrollments[experiment.name] = (alternative, None, timestamp_from_datetime(enrollment_date or now()), timestamp_from_datetime(last_seen)) self.session['experiments_enrollments'] = enrollments if self._is_verified_human(): self.experiment_counter.increment_participant_count(experiment, alternative, self._participant_identifier()) user_enrolled.send( self, experiment=experiment.name, alternative=alternative, user=None, session=self.session)