Skip to content
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

WIP Add dependency-injector to Tribler #6197

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion experiment/popularity_community/crawl_torrents.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ def create_config(working_dir, config_path):
async def on_tribler_started(self):
await super().on_tribler_started()
session = self.session
peer = Peer(session.trustchain_keypair)
peer = Peer(session.trustchain_keys.keypair)

crawler_settings = SimpleNamespace(output_file_path=self._output_file_path,
peers_count_csv_file_path=self._peers_count_csv_file_path)
Expand Down
13 changes: 10 additions & 3 deletions experiment/popularity_community/initial_filling.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@

from ipv8.peer import Peer
from ipv8.peerdiscovery.discovery import RandomWalk
from tribler_core import containers
from tribler_core.modules.popularity.community import PopularityCommunity
from tribler_core.modules.remote_query_community.settings import RemoteQueryCommunitySettings
from tribler_core.modules.popularity.popularity_community import PopularityCommunity
from tribler_core.session import Session
from tribler_core.utilities.tiny_tribler_service import TinyTriblerService

_logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -67,12 +69,17 @@ def check(self):

class Service(TinyTriblerService):
def __init__(self, interval_in_sec, output_file_path, timeout_in_sec, working_dir, config_path):
super().__init__(Service.create_config(working_dir, config_path), timeout_in_sec,
config = Service.create_config(working_dir, config_path)
super().__init__(config, timeout_in_sec,
working_dir, config_path)

self._interval_in_sec = interval_in_sec
self._output_file_path = output_file_path

self.application = containers.ApplicationContainer(state_dir=config.state_dir)
self.application.config.from_pydantic(config)
self.application.wire(modules=[Session])
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A good start point to discover PR.


@staticmethod
def create_config(working_dir, config_path):
config = TinyTriblerService.create_default_config(working_dir, config_path)
Expand All @@ -85,7 +92,7 @@ async def on_tribler_started(self):
await super().on_tribler_started()

session = self.session
peer = Peer(session.trustchain_keypair)
peer = Peer(session.trustchain_keys.keypair)

session.popularity_community = ObservablePopularityCommunity(self._interval_in_sec,
self._output_file_path,
Expand Down
1 change: 1 addition & 0 deletions src/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ netifaces
pyqtgraph
yappi
pydantic
dependency-injector
11 changes: 11 additions & 0 deletions src/run_tribler.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from tribler_common.sentry_reporter.sentry_reporter import SentryReporter, SentryStrategy
from tribler_common.sentry_reporter.sentry_scrubber import SentryScrubber
from tribler_common.version_manager import VersionHistory
from tribler_core import containers
from tribler_core.dependencies import check_for_missing_dependencies
from tribler_core.modules.community_loader import create_default_loader
from tribler_core.utilities.osutils import get_root_state_directory
Expand Down Expand Up @@ -92,6 +93,16 @@ async def start_tribler():
trace_logger = check_and_enable_code_tracing('core', log_dir)

community_loader = create_default_loader(config)

application = containers.ApplicationContainer(state_dir=config.state_dir)
application.config.from_pydantic(config)

if core_test_mode:
from ipv8.messaging.interfaces.dispatcher.endpoint import DispatcherEndpoint
application.ipv8_container.endpoint = DispatcherEndpoint([])

application.wire(modules=[Session])

session = Session(config, core_test_mode=core_test_mode, community_loader=community_loader)

signal.signal(signal.SIGTERM, lambda signum, stack: shutdown(session, signum, stack))
Expand Down
2 changes: 1 addition & 1 deletion src/tribler-core/run_bandwidth_crawler.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def get_kwargs(self, session):
settings = BandwidthAccountingSettings()
settings.outgoing_query_interval = 5
database = BandwidthDatabase(session.config.state_dir / "sqlite" / "bandwidth.db",
session.trustchain_keypair.pub().key_to_bin(), store_all_transactions=True)
session.trustchain_keys.keypair.pub().key_to_bin(), store_all_transactions=True)

return {
"database": database,
Expand Down
36 changes: 36 additions & 0 deletions src/tribler-core/tribler_core/containers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from ipv8.messaging.interfaces.dispatcher.endpoint import DispatcherEndpoint
from ipv8.peer import Peer

from ipv8_service import IPv8

from dependency_injector import containers, providers

from tribler_core.ipv8_config import Ipv8Config
from tribler_core.trustchain_keys import TrustChainKeys


class Ipv8Container(containers.DeclarativeContainer):
state_dir = providers.Dependency()
config = providers.Configuration()

ipv8_config = providers.Singleton(Ipv8Config, state_dir=state_dir, config=config.provider)

endpoint = providers.Singleton(
DispatcherEndpoint,
providers.List(providers.Object("UDPIPv4")),
UDPIPv4=providers.Dict(port=providers.Factory(config.port), ip=providers.Factory(config.address)),
Copy link
Contributor

@ichorid ichorid Jul 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, this line looks not too intuitive 😕. I would expect it to be just UDPIPv4={'port':config.port}, etc. Why the Factory stuff is necessary here, what's the semantic reason? Lazy initialization?

Copy link
Contributor Author

@drew2a drew2a Jul 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be replaced by:

    endpoint = providers.Singleton(
        DispatcherEndpoint, ["UDPIPv4"],
        UDPIPv4=providers.Dict(port=config.port, ip=config.address),
    )

Explanations later...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use UDPIPv4={'port':config.port} you'll get:

{'UDPIPv4': {'port': <dependency_injector.providers.ConfigurationOption('config.port') at 0x112961eb0>}}

)

ipv8 = providers.Singleton(
IPv8, ipv8_config.provided.value, enable_statistics=config.statistics, endpoint_override=endpoint
)


class ApplicationContainer(containers.DeclarativeContainer):
state_dir = providers.Dependency()
config = providers.Configuration()

trustchain_keys = providers.Singleton(TrustChainKeys, state_dir=state_dir, config=config.provider)
peer = providers.Singleton(Peer, trustchain_keys.provided.trustchain_keypair)

ipv8_container = providers.Container(Ipv8Container, state_dir=state_dir, config=config.ipv8)
15 changes: 15 additions & 0 deletions src/tribler-core/tribler_core/ipv8_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from ipv8.configuration import ConfigBuilder


class Ipv8Config:
"""Extracted from session.py"""

def __init__(self, state_dir=None, config=None):
self.value = (ConfigBuilder()
.set_port(config.port())
.set_address(config.address())
.clear_overlays()
.clear_keys() # We load the keys ourselves
.set_working_directory(str(state_dir))
.set_walker_interval(config.walk_interval())
.finalize())
16 changes: 11 additions & 5 deletions src/tribler-core/tribler_core/modules/community_loader.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# pylint: disable=import-outside-toplevel
from dependency_injector.wiring import Provide

from ipv8.loader import (
CommunityLauncher,
IPv8CommunityLoader,
Expand All @@ -9,6 +11,7 @@
walk_strategy,
)
from ipv8.peer import Peer
from tribler_core import containers

from tribler_core.config.tribler_config import TriblerConfig

Expand All @@ -22,7 +25,7 @@ class TriblerCommunityLauncher(CommunityLauncher):
def get_my_peer(self, ipv8, session):
trustchain_testnet = session.config.general.testnet or session.config.trustchain.testnet
return (Peer(session.trustchain_testnet_keypair) if trustchain_testnet
else Peer(session.trustchain_keypair))
else Peer(session.trustchain_keys.keypair))

def get_bootstrappers(self, session):
from ipv8.bootstrapping.dispersy.bootstrapper import DispersyBootstrapper
Expand Down Expand Up @@ -89,6 +92,9 @@ class IPv8DiscoveryCommunityLauncher(TriblerCommunityLauncher):
class DHTCommunityLauncher(TriblerCommunityLauncher):
pass

# def load_communities(ipv8 = Provide[containers.Ipv8Container.ipv8], peer = Provide[containers.Ipv8Container.peer]):
#
# pass

def create_default_loader(config: TriblerConfig):
loader = IPv8CommunityLoader()
Expand All @@ -112,10 +118,10 @@ def create_default_loader(config: TriblerConfig):
if config.tunnel_community.enabled and tunnel_testnet:
from tribler_core.modules.tunnel.community.launcher import TriblerTunnelTestnetCommunityLauncher
loader.set_launcher(TriblerTunnelTestnetCommunityLauncher())

if config.popularity_community.enabled:
from tribler_core.modules.popularity.launcher import PopularityCommunityLauncher
loader.set_launcher(PopularityCommunityLauncher())
#
# if config.popularity_community.enabled:
# from tribler_core.modules.popularity.launcher import PopularityCommunityLauncher
# loader.set_launcher(PopularityCommunityLauncher())

chant_testnet = config.general.testnet or config.chant.testnet
if config.chant.enabled and not chant_testnet:
Expand Down
5 changes: 5 additions & 0 deletions src/tribler-core/tribler_core/modules/container.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from dependency_injector import containers


class CommunityContainer(containers.DeclarativeContainer):
...
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def create_session(self, hops=0, store_listen_port=True):
pe_settings.prefer_rc4 = True
ltsession.set_pe_settings(pe_settings)

mid = self.tribler_session.trustchain_keypair.key_to_hash()
mid = self.tribler_session.trustchain_keys.keypair.key_to_hash()
settings['peer_fingerprint'] = mid
settings['handshake_client_version'] = 'Tribler/' + version_id + '/' + hexlify(mid)
else:
Expand Down
27 changes: 27 additions & 0 deletions src/tribler-core/tribler_core/modules/popularity/containers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from dependency_injector import providers

from ipv8.peerdiscovery.discovery import RandomWalk
from tribler_core.modules import container
from tribler_core.modules.metadata_store.community.sync_strategy import RemovePeers
from tribler_core.modules.popularity.community import PopularityCommunity


class PopularityCommunityContainer(container.CommunityContainer):
config = providers.Configuration()
rqc_config = providers.Configuration()

metadata_store = providers.Dependency()
torrent_checker = providers.Dependency()

peer = providers.Dependency()
endpoint = providers.Dependency()
network = providers.Dependency()

community = providers.Factory(PopularityCommunity, peer, endpoint, network,
settings=config, rqc_settings=rqc_config,
metadata_store=metadata_store, torrent_checker=torrent_checker)

strategies = providers.List(
providers.Factory(RandomWalk, community, target_peers=30),
providers.Factory(RemovePeers, community, target_peers=-1),
)
Loading