Skip to content

Replace Twisted inlineCallbacks with coroutines #3424

@lunkwill42

Description

@lunkwill42

Is your feature request related to a problem? Please describe.

The @inlineCallbacks decorator is used everywhere in the ipdevpoll codebase in NAV (except for the earliest parts, which were written before the introduction of this decorator, or at least before we learned of it).

This Twisted decorator is mostly a holdover from Python 2, which didn't have syntax for coroutines. The decorator allows for making coroutine-like functions by converting them into generators.

Under Python 3 and newer Twisted versions, this decorator isn't really necessary, as Python coroutines can work with Twisted.

Quoting from https://patrick.cloke.us/posts/2021/06/11/converting-twisteds-inlinecallbacks-to-async/ , benefits to converting functions decorated with @inlineCallbacks to pure coroutines include:

  • inlineCallbacks mangle stack traces, while async/await does not (as much). This helps with profiling and understanding exceptions.
  • async/await is more modern and standard — there’s a better chance of people understanding it who don’t haven’t used Twisted before.
  • async/await has better support from other packages, static analyzers, tools, etc.
  • async functions can provide better type hints for return values.

Twisted documentation also recommends coroutines for code that doesn't need to stay compatible with Python 2, and claims they are also more efficient.

Describe the solution you'd like

We should break down this issue into multiple sub-issues for groups of @inlineCallbacks usage in the NAV codebase, and try to convert all usages into coroutines. The overview presented in https://patrick.cloke.us/posts/2021/06/11/converting-twisteds-inlinecallbacks-to-async/ applies, especially the fact that parts of our codebase expects Deferred objects to be returned from @inlineCallbacks decorated functions, and these return values must be wrapped in ensureDeferred() calls to still work (or be rewritten to work differently).

Moving away from this decorator and to more pure Python async code may be a stepping stone to be able to replace Twisted with Python's built-in asyncio at some point.

Describe alternatives you've considered

Leave things to rot as they are, until we find one day that the decorator is deprecated by Twisted.

Additional context

Files that use inlineCallbacks today:

These files are all listed as TODO-able items here, but some of them could ostensibly be grouped into more logical collections and made into sub-issues (and, regardless, any changes made in these files may have ramifications for how the decorated functions are called from other files):

One example of a potential grouping could be MibRetriever subclasses that all implement the same external interface, such as get_all_sensors(). It would make sense to convert all implementations of this method as one.

Sub-issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions