Simulátor distribuované sítě (2)

Užitečné odkazy

Odbočka: Struktura knihovny

Naši knihovnu bude vhodné rozdělit minimálně do několika souborů. Dobrým zvykem je udržovat jednu třídu v jednom Python souboru. Soubor by měl být pojmenován malými písmeny. Například tedy nazev_tridy.py, v tomto souboru je umístěna třída NazevTridy. Z ostatních souborů mohu poté provádět import této třídy za pomoci výrazu from nazev_tridy import NazevTridy.

Ukázková struktura projektu by tedy mohla být následující:

1
2
3
-rw-r--r--  1 tomasmikula  staff  1032 Oct 31 18:44 main.py
-rw-r--r--  1 tomasmikula  staff  1067 Oct 31 18:29 network.py
-rw-r--r--  1 tomasmikula  staff   681 Oct 30 21:35 node.py

V souboru main.py provádíme základní vytvoření sítě a nastavení topologie. Takto vytvořené třídy můžeme importovat i v rámci interaktivní konzole Pythonu, nemusíme tedy vůbec vytvářet hlavní soubor.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import logging
import multiprocessing
import time

from multiprocessing.connection import wait
from multiprocessing import Pipe, Process, current_process

# Importy z nasi knihovny
from network import Network

# Konstatnty
TOPOLOGY = [[False, True, False],
            [False, False, True],
            [True, False, False]]

LOGGER = multiprocessing.log_to_stderr()
LOGGER.setLevel(logging.INFO)

# Definice funkci
def function():
    """Function for node"""

    node = current_process()

    for output_node in node.out_pipes.values():
        for connection in output_node:
            connection.send("Msg from node {}".format(node.name))

    for input_node in node.in_pipes.values():
        for connection in input_node:
            LOGGER.info("Node: {}, Msg: {}".format(node.name,
                                                   connection.recv()))

    time.sleep(2)


# main, tento kod nebude spusten pri beznem importu,
# pouze pri spusteni souboru python main.py
if __name__ == '__main__':
    NETWORK = Network([function for i in range(len(TOPOLOGY))], TOPOLOGY)
    NETWORK.start()
    NETWORK.join()

Rozšíření knihovny: Možnost předávat argumenty uzlům

Aktuálně umí naše knihovna spouštět každý uzel s jiným kódem. Neumí však předávat argumenty funkci v daném uzlu. Upravte knihovnu tak, aby kromě seznamu funkcí bylo možné předat i seznam argumentů (seznam tuples).

1
2
3
4
NETWORK = Network(
    [function1, function2, function3],
    [(1,), (2,), (3,)],
    TOPOLOGY)

Rozšíření knihovny: Možnost přijímat zprávy pouze od nějakého uzlu

Do knihovny přidejte funkcionalitu, aby v kódu uzlu bylo možné přijímat zprávy pouze od jiného názvem určeného uzlu.

1
2
3
4
node = current_process()

# prijme zpravy pouze od Node s nazvem "0"
node.recv_from(0)

Rozšíření knihovny: Možnost zaslat zprávu cílovému uzlu

Do knihovny přidejte funkcionalitu, aby v kódu uzlu bylo možné posílat zprávy jinému názvem určenému uzlu.

1
2
3
4
node = current_process()

# prijme zpravy pouze od Node s nazvem "0"
node.send_to(0, msg)

Rozšíření knihovny: Možnost příjmutí náhodné zprávy

Do knihovny pridejte funkcionalitu, aby v kódu uzlu bylo možné přijmout náhodnou zprávu z jakéhokoli input kanálu, který nějakou zprávu obsahuje.

1
2
3
node = current_process()

node.recv_any()