Apply async mode optimization

This commit is contained in:
Roman Mogylatov 2022-03-27 19:23:57 -04:00
parent ae1d00d107
commit b4fb9a7178
4 changed files with 4212 additions and 3947 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,10 @@ import functools
cimport cython cimport cython
cdef int ASYNC_MODE_UNDEFINED
cdef int ASYNC_MODE_ENABLED
cdef int ASYNC_MODE_DISABLED
cdef set __iscoroutine_typecache cdef set __iscoroutine_typecache
cdef tuple __COROUTINE_TYPES cdef tuple __COROUTINE_TYPES
@ -387,11 +391,13 @@ cdef inline object __provide_positional_args(
tuple args, tuple args,
tuple inj_args, tuple inj_args,
int inj_args_len, int inj_args_len,
int async_mode,
): ):
cdef int index cdef int index
cdef list positional_args = [] cdef list positional_args = []
cdef list future_args = [] cdef list future_args = []
cdef PositionalInjection injection cdef PositionalInjection injection
cdef object value
if inj_args_len == 0: if inj_args_len == 0:
return args return args
@ -401,7 +407,7 @@ cdef inline object __provide_positional_args(
value = __get_value(injection) value = __get_value(injection)
positional_args.append(value) positional_args.append(value)
if __is_future_or_coroutine(value): if async_mode != ASYNC_MODE_DISABLED and __is_future_or_coroutine(value):
future_args.append((index, value)) future_args.append((index, value))
positional_args.extend(args) positional_args.extend(args)
@ -418,6 +424,7 @@ cdef inline object __provide_keyword_args(
dict kwargs, dict kwargs,
tuple inj_kwargs, tuple inj_kwargs,
int inj_kwargs_len, int inj_kwargs_len,
int async_mode,
): ):
cdef int index cdef int index
cdef object name cdef object name
@ -432,7 +439,7 @@ cdef inline object __provide_keyword_args(
name = __get_name(kw_injection) name = __get_name(kw_injection)
value = __get_value(kw_injection) value = __get_value(kw_injection)
kwargs[name] = value kwargs[name] = value
if __is_future_or_coroutine(value): if async_mode != ASYNC_MODE_DISABLED and __is_future_or_coroutine(value):
future_kwargs.append((name, value)) future_kwargs.append((name, value))
else: else:
kwargs, prefixed = __separate_prefixed_kwargs(kwargs) kwargs, prefixed = __separate_prefixed_kwargs(kwargs)
@ -451,7 +458,7 @@ cdef inline object __provide_keyword_args(
value = __get_value(kw_injection) value = __get_value(kw_injection)
kwargs[name] = value kwargs[name] = value
if __is_future_or_coroutine(value): if async_mode != ASYNC_MODE_DISABLED and __is_future_or_coroutine(value):
future_kwargs.append((name, value)) future_kwargs.append((name, value))
if future_kwargs: if future_kwargs:
@ -554,18 +561,24 @@ cdef inline object __call(
dict context_kwargs, dict context_kwargs,
tuple injection_kwargs, tuple injection_kwargs,
int injection_kwargs_len, int injection_kwargs_len,
int async_mode,
): ):
cdef object args = __provide_positional_args( cdef object args = __provide_positional_args(
context_args, context_args,
injection_args, injection_args,
injection_args_len, injection_args_len,
async_mode,
) )
cdef object kwargs = __provide_keyword_args( cdef object kwargs = __provide_keyword_args(
context_kwargs, context_kwargs,
injection_kwargs, injection_kwargs,
injection_kwargs_len, injection_kwargs_len,
async_mode,
) )
if async_mode == ASYNC_MODE_DISABLED:
return call(*args, **kwargs)
cdef bint is_future_args = __is_future_or_coroutine(args) cdef bint is_future_args = __is_future_or_coroutine(args)
cdef bint is_future_kwargs = __is_future_or_coroutine(kwargs) cdef bint is_future_kwargs = __is_future_or_coroutine(kwargs)
@ -613,7 +626,7 @@ cdef inline object __async_result_callback(object future_result, object future):
future_result.set_result(result) future_result.set_result(result)
cdef inline object __callable_call(Callable self, tuple args, dict kwargs): cdef inline object __callable_call(Callable self, tuple args, dict kwargs, ):
return __call( return __call(
self.__provides, self.__provides,
args, args,
@ -622,13 +635,23 @@ cdef inline object __callable_call(Callable self, tuple args, dict kwargs):
kwargs, kwargs,
self.__kwargs, self.__kwargs,
self.__kwargs_len, self.__kwargs_len,
self.__async_mode,
) )
cdef inline object __factory_call(Factory self, tuple args, dict kwargs): cdef inline object __factory_call(Factory self, tuple args, dict kwargs):
cdef object instance cdef object instance
instance = __callable_call(self.__instantiator, args, kwargs) instance = __call(
self.__instantiator.__provides,
args,
self.__instantiator.__args,
self.__instantiator.__args_len,
kwargs,
self.__instantiator.__kwargs,
self.__instantiator.__kwargs_len,
self.__async_mode,
)
if self.__attributes_len > 0: if self.__attributes_len > 0:
attributes = __provide_attributes(self.__attributes, self.__attributes_len) attributes = __provide_attributes(self.__attributes, self.__attributes_len)

View File

@ -3410,7 +3410,7 @@ cdef class List(Provider):
cpdef object _provide(self, tuple args, dict kwargs): cpdef object _provide(self, tuple args, dict kwargs):
"""Return result of provided callable call.""" """Return result of provided callable call."""
return __provide_positional_args(args, self.__args, self.__args_len) return __provide_positional_args(args, self.__args, self.__args_len, self.__async_mode)
cdef class Dict(Provider): cdef class Dict(Provider):
@ -3536,7 +3536,7 @@ cdef class Dict(Provider):
cpdef object _provide(self, tuple args, dict kwargs): cpdef object _provide(self, tuple args, dict kwargs):
"""Return result of provided callable call.""" """Return result of provided callable call."""
return __provide_keyword_args(kwargs, self.__kwargs, self.__kwargs_len) return __provide_keyword_args(kwargs, self.__kwargs, self.__kwargs_len, self.__async_mode)
@ -3739,6 +3739,7 @@ cdef class Resource(Provider):
kwargs, kwargs,
self.__kwargs, self.__kwargs,
self.__kwargs_len, self.__kwargs_len,
self.__async_mode,
) )
self.__shutdowner = initializer.shutdown self.__shutdowner = initializer.shutdown
elif self._is_async_resource_subclass(self.__provides): elif self._is_async_resource_subclass(self.__provides):
@ -3751,6 +3752,7 @@ cdef class Resource(Provider):
kwargs, kwargs,
self.__kwargs, self.__kwargs,
self.__kwargs_len, self.__kwargs_len,
self.__async_mode,
) )
self.__initialized = True self.__initialized = True
return self._create_init_future(async_init, initializer.shutdown) return self._create_init_future(async_init, initializer.shutdown)
@ -3763,6 +3765,7 @@ cdef class Resource(Provider):
kwargs, kwargs,
self.__kwargs, self.__kwargs,
self.__kwargs_len, self.__kwargs_len,
self.__async_mode,
) )
self.__resource = next(initializer) self.__resource = next(initializer)
self.__shutdowner = initializer.send self.__shutdowner = initializer.send
@ -3775,6 +3778,7 @@ cdef class Resource(Provider):
kwargs, kwargs,
self.__kwargs, self.__kwargs,
self.__kwargs_len, self.__kwargs_len,
self.__async_mode,
) )
self.__initialized = True self.__initialized = True
return self._create_init_future(initializer) return self._create_init_future(initializer)
@ -3787,6 +3791,7 @@ cdef class Resource(Provider):
kwargs, kwargs,
self.__kwargs, self.__kwargs,
self.__kwargs_len, self.__kwargs_len,
self.__async_mode,
) )
self.__initialized = True self.__initialized = True
return self._create_async_gen_init_future(initializer) return self._create_async_gen_init_future(initializer)
@ -3799,6 +3804,7 @@ cdef class Resource(Provider):
kwargs, kwargs,
self.__kwargs, self.__kwargs,
self.__kwargs_len, self.__kwargs_len,
self.__async_mode,
) )
else: else:
raise Error("Unknown type of resource initializer") raise Error("Unknown type of resource initializer")
@ -4513,6 +4519,7 @@ cdef class MethodCaller(Provider):
kwargs, kwargs,
self.__kwargs, self.__kwargs,
self.__kwargs_len, self.__kwargs_len,
self.__async_mode,
) )
def _async_provide(self, future_result, args, kwargs, future): def _async_provide(self, future_result, args, kwargs, future):
@ -4526,6 +4533,7 @@ cdef class MethodCaller(Provider):
kwargs, kwargs,
self.__kwargs, self.__kwargs,
self.__kwargs_len, self.__kwargs_len,
self.__async_mode,
) )
except Exception as exception: except Exception as exception:
future_result.set_exception(exception) future_result.set_exception(exception)