Ограничение вызовов на внешнюю базу данных с помощью Python CGI - PullRequest
0 голосов
/ 16 декабря 2009

У меня есть скрипт Python CGI, который извлекает данные из службы GPS; Я хотел бы, чтобы эта информация обновлялась на веб-странице примерно раз в 10 секунд (максимальное значение, допустимое с помощью службы GPS). Но, скажем, 100 пользователей одновременно просматривают веб-страницу, и все они вызывают сценарий.

Я думаю, что пользовательские скрипты должны получать данные со страницы буфера, которая сама обновляется только раз в десять секунд. Как я могу сделать автоматическое обновление этой страницы буфера, если никто не просматривает контент напрямую (и не имеет доступа к CGI)? Есть ли лучшие способы сделать это?

1 Ответ

1 голос
/ 16 декабря 2009

Кэшируйте результаты вашего запроса данных GPS в файл или базу данных (sqlite) вместе с датой и временем.

Затем можно выполнить проверку даты и времени по отношению к последней кэшированной дате и времени, чтобы инициировать другой запрос данных GPS.

Возможно, вы столкнетесь с проблемами параллелизма с cgi и проверкой даты и времени ...

Чтобы обойти проблемы параллелизма, вы можете использовать sqlite и поместить запись в попытку / исключение. Вот пример реализации кэша с использованием sqlite.

import datetime
import sqlite3 

class GpsCache(object):
    db_path = 'gps_cache.db'
    def __init__(self):
        self.con = sqlite3.connect(self.db_path)
        self.cur = self.con.cursor()

    def _get_period(self, dt=None):
        '''normalize time to 15 minute periods'''
        if dt.minute < 15:
           minute_period = 0
        elif 15 <= dt.minute < 30:
           minute_period = 15
        elif 30 <= dt_minute < 45: 
           minute_period = 30
        elif 45 <= dt_minute:
           minute_period = 25
        period_dt = datetime.datetime(year=dt.year, month=dt.month, day=dt.day, hour=dt.hour, minute=minute_period)
        return period_dt

    def get_cache(dt=None):
        period_dt = self._get_period(dt)
        select_sql = 'SELECT * FROM GPS_CACHE WHERE date_time = "%s";' % period_dt.strftime('%Y-%m-%d %H:%M')
        self.cur.execut(select_sql)
        result = self.cur.fetchone()[0]
        return result


    def put_cache(dt=None, data=None):
        period_dt = self._get_period(dt)
        insert_sql = 'INSERT ....'  # edit to your table structure
        try:
            self.cur.execute(insert_sql)
            self.con.commit()
        except sqlite3.OperationalError:
            # assume db is being updated by another process with the current resutls and ignore
            pass

Итак, теперь у нас есть инструмент кэширования на стороне реализации.

Сначала вы захотите проверить кеш, а затем, если он не «свежий» (ничего не возвращает), перейдите к получению данных, используя ваш текущий метод. Затем кэшируйте данные, которые вы захватили. Вы, вероятно, должны организовать это лучше, но вы должны получить общее представление здесь.

Используя этот пример, вы просто заменяете текущие вызовы на «remote_get_gps_data» на «get_gps_data».

from gps_cacher import GpsCache

def remote_get_gps_data():
    # your function here
    return data

def get_gps_data():
    data = None
    gps_cache = GpsCache()
    current_dt = datetime.datetime.now()
    cached_data = gps_cache.get_cache(current_dt)    
    if cached_data:
        data = cached_data
    else:
        data = remote_get_gps_data()
        gps_cache.put_cache(current_dt, data)
    return data
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...