У меня есть безсерверная функция, вызывающая базу данных 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)