source: trunk/src/allmydata/listeners.py

Last change on this file was 024b5e4, checked in by Jean-Paul Calderone <exarkun@…>, at 2023-07-20T18:23:31Z

narrow the type annotation for another Listener method param

  • Property mode set to 100644
File size: 3.7 KB
Line 
1"""
2Define a protocol for listening on a transport such that Tahoe-LAFS can
3communicate over it, manage configuration for it in its configuration file,
4detect when it is possible to use it, etc.
5"""
6
7from __future__ import annotations
8
9from typing import Any, Protocol, Sequence, Mapping, Optional, Union, Awaitable
10from typing_extensions import Literal
11
12from attrs import frozen
13from twisted.python.usage import Options
14
15from .interfaces import IAddressFamily
16from .util.iputil import allocate_tcp_port
17from .node import _Config
18
19@frozen
20class ListenerConfig:
21    """
22    :ivar tub_ports: Entries to merge into ``[node]tub.port``.
23
24    :ivar tub_locations: Entries to merge into ``[node]tub.location``.
25
26    :ivar node_config: Entries to add into the overall Tahoe-LAFS
27        configuration beneath a section named after this listener.
28    """
29    tub_ports: Sequence[str]
30    tub_locations: Sequence[str]
31    node_config: Mapping[str, Sequence[tuple[str, str]]]
32
33class Listener(Protocol):
34    """
35    An object which can listen on a transport and allow Tahoe-LAFS
36    communication to happen over it.
37    """
38    def is_available(self) -> bool:
39        """
40        Can this type of listener actually be used in this runtime
41        environment?
42        """
43
44    def can_hide_ip(self) -> bool:
45        """
46        Can the transport supported by this type of listener conceal the
47        node's public internet address from peers?
48        """
49
50    async def create_config(self, reactor: Any, cli_config: Options) -> Optional[ListenerConfig]:
51        """
52        Set up an instance of this listener according to the given
53        configuration parameters.
54
55        This may also allocate ephemeral resources if necessary.
56
57        :return: The created configuration which can be merged into the
58            overall *tahoe.cfg* configuration file.
59        """
60
61    def create(self, reactor: Any, config: _Config) -> IAddressFamily:
62        """
63        Instantiate this listener according to the given
64        previously-generated configuration.
65
66        :return: A handle on the listener which can be used to integrate it
67            into the Tahoe-LAFS node.
68        """
69
70class TCPProvider:
71    """
72    Support plain TCP connections.
73    """
74    def is_available(self) -> Literal[True]:
75        return True
76
77    def can_hide_ip(self) -> Literal[False]:
78        return False
79
80    async def create_config(self, reactor: Any, cli_config: Options) -> ListenerConfig:
81        tub_ports = []
82        tub_locations = []
83        if cli_config["port"]: # --port/--location are a pair
84            tub_ports.append(cli_config["port"])
85            tub_locations.append(cli_config["location"])
86        else:
87            assert "hostname" in cli_config
88            hostname = cli_config["hostname"]
89            new_port = allocate_tcp_port()
90            tub_ports.append(f"tcp:{new_port}")
91            tub_locations.append(f"tcp:{hostname}:{new_port}")
92
93        return ListenerConfig(tub_ports, tub_locations, {})
94
95    def create(self, reactor: Any, config: _Config) -> IAddressFamily:
96        raise NotImplementedError()
97
98
99@frozen
100class StaticProvider:
101    """
102    A provider that uses all pre-computed values.
103    """
104    _available: bool
105    _hide_ip: bool
106    _config: Union[Awaitable[Optional[ListenerConfig]], Optional[ListenerConfig]]
107    _address: IAddressFamily
108
109    def is_available(self) -> bool:
110        return self._available
111
112    def can_hide_ip(self) -> bool:
113        return self._hide_ip
114
115    async def create_config(self, reactor: Any, cli_config: Options) -> Optional[ListenerConfig]:
116        if self._config is None or isinstance(self._config, ListenerConfig):
117            return self._config
118        return await self._config
119
120    def create(self, reactor: Any, config: _Config) -> IAddressFamily:
121        return self._address
Note: See TracBrowser for help on using the repository browser.