Использование всегда асинхронных операций ndb в ndb gae

Я работаю с gae и ndb и обнаружил, что мне нужно написать много кода для запросов и запросов ndb. Иногда мне нужны две версии (иногда 3 или более).

Предположим, у меня есть следующие модели и функции внутри них:

class MainEnt(ndb.Model):
    """Main entity. The parent is the user_key"""
    name = ndb.StringProperty()
    child = ndb.KeyProperty()

    def get_created_by(self, user_id):
        """Get the MainEnt's created by user_id"""
        # stuff... getting the query and returning the results

    def get_created_by_async(self, user_id):
        """Get async the MainEnt's created by user_id"""
        # stuff... getting the query async and returning a future

    @ndb.tasklet
    def get_childs_async_tasklet(self, mainent_key):
        """Get async the childs of a MainEnt"""
        # stuff... yielding the query async. and raise ndb.Return()...

    @ndb.tasklet
    def get_created_by_async_tasklet(self, user_id):
        """Get async the MainEnt's created by user_id"""
        # stuff... yielding the query async. and raise ndb.Return()...

    @ndb.tasklet
    def get_created_by_async_tasklet_with_childs(self, user_id):
        """Get async the MainEnt's created by user_id and its childs"""
        # stuff... yielding the query async. calling get_childs.. and raise ndb.Return()...

    @ndb.tasklet
    def get_voted_by_async_tasklet(self, user_id):
        """Get async the MainEnt's voted by user_id"""
        # stuff... yielding the query async raise ndb.Return()...

    @ndb.tasklet
    def get_voted_by_async_tasklet_with_childs(self, user_id):
        """Get async the MainEnt's voted by user_id and it's childs"""
        # stuff... yielding the query async, calling get_childs.. and raise ndb.Return()...

    @ndb.tasklet
    def get_created_and_voted_by_async_tasklet(self, user_id):
        """yield get_created_by_async_tasklet and get_voted_by_async_tasklet in parallel"""
        # stuff... yielding the other two functions and return results...

class ChildEnt(ndb.Model):
    name = ndb.StringProperty()

Как вы видите, MainEnt имеет три метода, которые возвращают "одинаковые" (иногда больше) результаты, но используются в разных контекстах.

1) Функция синхронизации используется только тогда, когда мне нужно получить результаты, и получение этих результатов является единственной "операцией ndb".

2) Асинхронная функция используется только тогда, когда мне нужно получить результаты, но я также выполняю другой запрос ndb, который я хочу перекрыть.

3) Асинхронная функция тасклета используется только тогда, когда мне нужно получить результаты, получить дочерние объекты этих результатов и, возможно, также выполнить какую-то другую операцию ndb.

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

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

Есть ли какие-либо неудобства в отношении производительности, подверженности ошибкам и т. Д. При выполнении этого? Я обнаружил, что гораздо проще всегда использовать асинхронный тасклет ndb для каждого запроса, получения и т. Д. И вызывать его результаты только в том случае, если мне тоже нужно или иначе выполнить больше асинхронных операций, а затем вызвать get_results.

Надеюсь, это хорошо объяснено...

Заранее спасибо!

1 ответ

Решение

Нет ничего плохого только в использовании асинхронных вызовов и немедленном использовании get_result, если вы хотите получить результаты синхронно. Это именно то, что делают синхронные функции ndb:

Вот пример из ndb.Key:

def get(self, **ctx_options):
    """Synchronously get the entity for this Key.

    Return None if there is no such entity.
    """
    return self.get_async(**ctx_options).get_result()
Другие вопросы по тегам