Функции Google превышают память - PullRequest
1 голос
/ 09 марта 2019

Мы развернули функцию python в функциях GCP, которая в основном получает HTTP POST JSON и призывает другую систему выполнить некоторую обработку.Эта другая система возвращает JSON, и мы отправляем JSON обратно исходному вызывающему.

Функция отлично работает с 128 Мб памяти, но после того, как мы получили нового клиента, они делают один вызов за другимфункции, и теперь GCP выдает ошибку превышения лимита памяти и прерывает процесс.

Я понимаю, что если клиент ждет несколько минут между вызовами, память возвращается обратно, но я не могу попросить их сделать это.

Мой вопрос: есть ли способ предотвратить такое значительное увеличение памяти после различных последовательных вызовов функции?Или какая-нибудь альтернатива, чтобы обнаружить его достижение до предела и отправить назад ошибку тайм-аута?

Часть моего кода

#!venv/bin/python
from flask import Flask, request, Response,jsonify,make_response
import json
import requests
from functools import wraps
import hashlib
from google.cloud import firestore
import datetime



app = Flask(__name__)
app.secret_key = b'NOTHERE'

def check_auth(username, password): 
    pwd = hashlib.sha1(str(password).encode('utf-8')).hexdigest()

    db = firestore.Client()

    users_ref = db.collection('XXX')
    doc_ref = users_ref.document(username)
    try:
        doc = doc_ref.get()
        dic = doc.to_dict()
        return pwd == dic['password']
    except:
        pass 

    return False

def authenticate():
    """Sends a 401 response that enables basic auth"""
    return Response(
    'Please Login', 401,
    {'WWW-Authenticate': 'Basic realm="Login Required"'})

def requires_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth = request.authorization
        if not auth or not check_auth(auth.username, auth.password):
            return authenticate()
        return f(*args, **kwargs)
    return decorated

#main function that google calls
@requires_auth
def brokering(request):
    db = firestore.Client()
    if request.method == 'POST':
    ......... here I do some write/reads on the firestore db

График памяти, пока он не сломается (130 вызовов)

enter image description here

1 Ответ

1 голос
/ 10 марта 2019

Я бы максимально переместился за пределы функции. Например, в настоящее время вы создаете два экземпляра firestore.Client(), один в brokering и один в check_auth, для каждого отдельного запроса. Вы должны переместить это за пределы ваших определений функций и повторно использовать один экземпляр клиента внутри функций.

Вы также делаете некоторые ненужные вещи, например, инициализируете целое приложение Flask, которое не используется облачными функциями, но расходует лишнюю память.

Я бы переписал всю вашу функцию так:

from flask import request, Response
from functools import wraps
import hashlib
from google.cloud import firestore

db = firestore.Client()
users_ref = db.collection('XXX')

def check_auth(username, password): 
    pwd = hashlib.sha1(str(password).encode('utf-8')).hexdigest()
    doc_ref = users_ref.document(username)

    try:
        return pwd == doc_ref.get().to_dict()['password']
    except:
        pass 

    return False

def authenticate():
    """Sends a 401 response that enables basic auth"""
    return Response(
    'Please Login', 401,
    {'WWW-Authenticate': 'Basic realm="Login Required"'})

def requires_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth = request.authorization
        if not auth or not check_auth(auth.username, auth.password):
            return authenticate()
        return f(*args, **kwargs)
    return decorated

@requires_auth
def brokering(request):
    if request.method == 'POST':
        ... # here I do some write/reads on the firestore db
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...