-
Notifications
You must be signed in to change notification settings - Fork 452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Loose coupling and sane folders structure #4953
Comments
I agree, much of the Tribler code was written when camelCase was still acceptable in Python. Let's also make sure we adhere to modern standards by using lowercase module names. |
@qstokkink , could you please compile a list of modern Python standards that we should adhere to during coding/refactoring? That should help the effort. |
Mostly it's just PEP8: https://www.python.org/dev/peps/pep-0008/#prescriptive-naming-conventions |
After discussing the thing with @qstokkink and @xoriole , we came up with the following folders structure:
This structure solves several problems:
In the
i.e. each Tribler component, such as Credit Mining or Metadata Store will get a separate directory. This directory will contain everything related to this module: IPv8 community, REST endpointss, config specifications, etc. This change paves the way to implementing a plugins system in Tribler. |
After discussion with @devos50 we decided that it will be better to include the tests besides the modules themselves in the code. This way, it will force the programmer to immediately think about the tests as an integral part of the code, and ease the code handling. |
Now that the folders structure is changed, we can start making Tribler modules use "lazy loading" strategy and being more independent from each other. Also, we can explore asynchronous start-up. |
Tribler source code now is at the point where we can completely remove the async def start_core(a,b):
foo = ComponentFoo(a,b)
await foo.start()
bar = ComponentBar(foo, b)
await bar.start()
await shutdown_future
await bar.shutdown()
await foo.shutdown() Furthermore, we can use the DependencyInjector framework to initialize components on-demand. This change will finally bring us loose coupling at the top level of Tribler Core, significantly simplifying all of the top-level architecture and tests. The next step after removing |
Solved by #6335 |
The Mess
Our source code directories structure is a mess. As is our import/modules structures (I don't even want to start on the topic of inconsistent dir names capitalization...). For some things, like REST endpoints, sources are grouped by function:
For other things by component:
(Note the inconsistent placement of modules!)
Another problem is the Config. Every component depends on the base Config object. When anyone wants to change something there, they have to add
get_*/set_*
methods directly into the Config class. As a result, the Config became a garbage dump. Also, it creates tight coupling and prevents submodules (like Anydex) from getting really independent (which defies the whole idea of having a submodule).The Solution
We can make Tribler more modularized, and component less dependent on each other by changing the source folders structure and moving component-specific sections of the Config class into the corresponding modules/components.
Directories
The directory structure could look like this:
Subconfigs
Subconfigs will enhance the root Config class as member objects, like this:
After joining LaunchMany with Session, we'll be able to loosen the coupling between Tribler components and make their initialisation sequences unified and straightforward, like this:
In this scheme,
ComponentConfig
objects could look like this:The root Config object will be the sole thing responsible for writing/reading stuff to disk. The downstream ComponentConfig objects will propagate the changes to it by the virtue of
dict
mutability.These changes will make the code structure much more straightforward, clear, and manageable.
The text was updated successfully, but these errors were encountered: