コード例 #1
0
ファイル: data.py プロジェクト: giacaglia/wigo2-server
def process_waitlist():
    from server.db import redis

    while True:
        lock = redis.lock('locks:process_waitlist', timeout=600)
        if lock.acquire(blocking=False):
            try:
                user_ids = wigo_db.sorted_set_range_by_score(
                    skey('user_queue'), 0, time(), 0, 50)
                if user_ids:
                    for user_id in user_ids:
                        logger.info('unlocking user id {}'.format(user_id))
                        user = User.find(user_id)
                        if user.is_waiting():
                            user.status = 'active'
                            user.save()

                        # remove from wait list
                        wigo_db.sorted_set_remove(skey('user_queue'),
                                                  user.id,
                                                  replicate=False)
                else:
                    break
            finally:
                lock.release()
コード例 #2
0
    def run(self):
        logger.info('running scheduled tasks')
        while True:
            lock = redis.lock('locks:run_schedule', timeout=60)
            if lock.acquire(blocking=False):
                try:
                    scheduler.enqueue_jobs()
                finally:
                    lock.release()

            sleep(5)
コード例 #3
0
ファイル: user.py プロジェクト: giacaglia/wigo2-server
def user_lock(user_id, timeout=30, yield_on_blocking_timeout=True):
    if Configuration.ENVIRONMENT != 'test':
        from server.db import redis

        lock = redis.lock('locks:user:{}'.format(user_id), timeout=timeout)
        if lock.acquire(blocking=True, blocking_timeout=5):
            try:
                yield
            finally:
                try:
                    lock.release()
                except LockError:
                    pass
        elif yield_on_blocking_timeout:
            yield
    else:
        yield
コード例 #4
0
ファイル: group.py プロジェクト: giacaglia/wigo2-server
    def create_from_city(cls, city):
        tz = get_timezone(city.lat, city.lon)
        city_code = city.name.decode('unicode_escape').encode(
            'ascii', 'ignore').lower()
        city_code = re.sub(r'[^\w]+', '_', city_code)

        for i in range(1, 10):
            lock = redis.lock('locks:group_create:{}'.format(city.city_id),
                              timeout=10)
            if lock.acquire(blocking=True, blocking_timeout=.1):
                try:
                    # look for the city one more time with the lock
                    return get_group_by_city_id(city.city_id)
                except DoesNotExist:
                    # create a new group with the lock acquired
                    try:
                        return Group({
                            'name': city.name,
                            'code': city_code,
                            'latitude': city.lat,
                            'longitude': city.lon,
                            'city_id': city.city_id,
                            'timezone': tz or 'US/Eastern',
                            'population': int(city.population),
                            'continent': city.continent,
                            'country': city.country,
                            'state': city.state,
                            'continent_id': city.continent_id,
                            'country_id': city.country_id,
                            'state_id': city.state_id
                        }).save()

                    except IntegrityException:
                        city_code = '{}_{}'.format(city_code, i)
                finally:
                    lock.release()

        raise DoesNotExist()
コード例 #5
0
    def run(self):
        logger.info('running maintenance tasks')
        while True:
            lock = redis.lock('locks:run_maintenance', timeout=60)
            if lock.acquire(blocking=False):
                try:
                    try:
                        process_waitlist()
                    except:
                        logger.exception('error processing waitlist')

                    try:
                        wigo_db.process_rate_limits()
                    except:
                        logger.exception('error processing rate limits')

                    try:
                        wigo_db.process_expired()
                    except:
                        logger.exception('error processing expired')

                    # kick off a job to cleanup old events
                    clean_old_events.delay()

                    # check the state of the queues
                    try:
                        for q_name in ALL_QUEUES:
                            self.check_queue(Queue(q_name, connection=redis),
                                             4000, 5)
                        f_queue = get_failed_queue(redis)
                        self.check_queue(f_queue, 20, 10)
                    except:
                        logger.exception('error checking queues')
                finally:
                    lock.release()

            sleep(60)
コード例 #6
0
ファイル: register.py プロジェクト: giacaglia/wigo2-server
    def post(self):
        data = request.get_json()

        if not data:
            abort(400, message='No data posted')

        timezone = pytz.timezone(data.get('timezone', 'US/Eastern'))
        facebook_id = data.get('facebook_id')
        facebook_token = data.get('facebook_access_token')
        facebook_token_expires = datetime.utcnow() + timedelta(
            seconds=data.get('facebook_access_token_expires') or 1728000)
        birthdate = data.get('birthdate')
        education = data.get('education')
        work = data.get('work')

        properties = data.get('properties')

        if not facebook_id or not facebook_token:
            abort(400, message='Missing facebook id or token')

        with redis.lock('locks:register:{}'.format(facebook_id), timeout=30):
            try:
                User.find(facebook_id=facebook_id)
                abort(400, message='Account already exists')
            except DoesNotExist:
                pass

            if not facebook_id.startswith('xxx'):
                facebook = Facebook(facebook_token, facebook_token_expires)
                user_info = self.get_me(facebook, facebook_id, facebook_token,
                                        facebook_token_expires)
                facebook_token_expires = facebook.get_token_expiration()
            else:
                user_info = {}

            logger.info('creating new user account for facebook_id {}'.format(
                facebook_id))

            user = User()
            user.key = uuid4().hex
            user.facebook_id = facebook_id
            user.facebook_token = facebook_token
            user.facebook_token_expires = facebook_token_expires

            user.email = user_info.get('email')
            if user.email:
                user.email_validated = True
                user.email_validated_date = datetime.utcnow()
                user.email_validated_status = 'validated'

            user.timezone = timezone.zone
            user.first_name = user_info.get('first_name') or user_info.get(
                'given_name')
            user.last_name = user_info.get('last_name') or user_info.get(
                'family_name')
            user.username = get_username(user.email or user.full_name)
            user.gender = user_info.get('gender')

            if not birthdate:
                birthdate = user_info.get('birthday')

            if birthdate:
                try:
                    user.birthdate = parse(birthdate)
                except:
                    logger.info('error parsing birthdate {}'.format(birthdate))

            if education:
                user.education = education

            if work:
                user.work = work

            if g.group:
                user.group_id = g.group.id

            if properties:
                for key, value in properties.items():
                    user.set_custom_property(key, value)

            user.set_custom_property('events', {'triggers': ['find_referrer']})

            platform = request.headers.get('X-Wigo-Device')
            if not platform:
                platform = request.user_agent.platform
            if platform:
                platform = platform.lower()

            if platform in ('android', 'iphone', 'ipad'):
                user.set_custom_property('platforms', [platform])

            enterprise = request.headers.get('X-Wigo-Client-Enterprise')
            if enterprise == 'true':
                user.enterprise = True

            user.save()

        g.user = user

        # if not user.email_validated and Configuration.PUSH_ENABLED:
        #     send_email_verification.delay(user.id)

        logger.info(
            'registered new account for user {} for facebook_id {}'.format(
                user.id, facebook_id))

        return self.serialize_list(User, [user])
コード例 #7
0
ファイル: data.py プロジェクト: giacaglia/wigo2-server
def event_related_change(group_id, event_id, is_global=False, deleted=False):
    from server.db import redis

    lock = redis.lock('locks:group_event_change:{}:{}'.format(
        group_id, event_id),
                      timeout=120)
    if lock.acquire(blocking=False):
        try:
            agent.add_custom_parameter('group_id', group_id)
            logger.debug('recording event change in group {}'.format(group_id))

            if not deleted:
                try:
                    event = Event.find(event_id)
                    event.deleted = False
                except DoesNotExist:
                    event = Event({'id': event_id, 'group_id': group_id})
                    event.deleted = True
            else:
                event = Event({'id': event_id, 'group_id': group_id})
                event.deleted = True

            group = Group.find(group_id)

            with wigo_db.transaction(commit_on_select=False):
                # add to the time in case other changes come in while this lock is taken,
                # or in case the job queues get backed up
                group.track_meta('last_event_change',
                                 time() + EVENT_CHANGE_TIME_BUFFER)

                if is_global or event.is_global:
                    groups_to_add_to = get_all_groups()
                else:
                    radius = 100
                    population = group.population or 50000
                    if population < 60000:
                        radius = 40
                    elif population < 100000:
                        radius = 60

                    groups_to_add_to = get_close_groups(
                        group.latitude, group.longitude, radius)

                num_visited = 0
                for group_to_add_to in groups_to_add_to:
                    if group_to_add_to.id == group.id:
                        continue

                    # index this event into the close group
                    if event.deleted is False:
                        event.update_global_events(group=group_to_add_to)
                    else:
                        event.remove_index(group=group_to_add_to)

                    # track the change for the group
                    group_to_add_to.track_meta(
                        'last_event_change',
                        time() + EVENT_CHANGE_TIME_BUFFER)

                    num_visited += 1

                    if (num_visited % 25) == 0:
                        lock.extend(30)

        finally:
            lock.release()