Кеширует ли библиотека Python Cloudant базу данных между выполнениями безсерверной функции? - PullRequest
0 голосов
/ 04 мая 2018

У меня есть безсерверная функция, вызывающая базу данных Cloudant через библиотеку python-cloudant , с подключением к клиенту вне обработчика функции, так что он кэшируется, например:

httpAdapter = HTTPAdapter(pool_connections=5, pool_maxsize=100)
client = Cloudant(cloudantUsername, cloudantPassword, url=cloudantURL, adapter=httpAdapter, connect=True)

def update(event, context):
    db = client['db_name']
    document_id = event['pathParameters']['id']
    document = db[document_id]
    document['foo'] = 'bar'
    document.save()
    return json.dumps(document)

def get(event, context):
    db = client['db_name']
    document_id = event['pathParameters']['id']
    document = db[document_id]
    return json.dumps(document)

Когда я делаю это, я получаю очень низкую задержку (<100 мс) при повторном выполнении любого вида (создание, обновление, получение), потому что «соединение» используется повторно, что и является намерением. («соединение» в кавычках, так как cloudant / couchdb не имеет концепции сохранения открытой трубы). </p>

Однако я заметил странное поведение - если я вызываю /update и увеличиваю документ _rev до 2-XXXX, то вызываю /get, функция возвращает документ с _rev 2-XXXX. Если я снова вызываю /update, _rev правильно увеличивается до 3-XXXX, но когда я снова вызываю /get, я получаю редакцию документа 2-XXXX (т.е. не обновленную версию). Когда это происходит, функция обновления выполняется за ~ 90 мс, а get выполняется за ~ 10 мс (слишком быстро, чтобы фактически вызывать базу данных).

Я могу устранить это поведение, переместив настройку клиента Cloudant в обработчик функций следующим образом:

httpAdapter = HTTPAdapter(pool_connections=5, pool_maxsize=100)

def update(event, context):
    client = Cloudant(cloudantUsername, cloudantPassword, url=cloudantURL, adapter=httpAdapter, connect=True)
    db = client['db_name']
    document_id = event['pathParameters']['id']
    document = db[document_id]
    document['foo'] = 'bar'
    document.save()
    return json.dumps(document)

def get(event, context):
    client = Cloudant(cloudantUsername, cloudantPassword, url=cloudantURL, adapter=httpAdapter, connect=True)
    db = client['db_name']
    document_id = event['pathParameters']['id']
    document = db[document_id]
    return json.dumps(document)

Когда я это делаю, /get всегда возвращает правильную версию документа. Такое поведение является неожиданным, поскольку я полагал, что установка установки клиента вне обработчика будет только кэшировать клиента между выполнениями, но вызовы базы данных будут по-прежнему выполняться каждый раз. Похоже, они создаются при вызове /update, но не при вызове /get.

Помещает ли объявление клиента вне обработчика как-то кеширование базы данных? Если так, есть ли способ предотвратить это?

Редактировать: Я обнаружил, что функцию можно принудительно вызвать в базу данных с клиентом, объявленным вне обработчика, путем явного вызова document.fetch(), например:

def get(event, context):
    db = client['db_name']
    document_id = event['pathParameters']['id']
    document = db[document_id]
    document.fetch()
    return json.dumps(document)
...