File: comm-failure.py

package info (click to toggle)
simgrid 4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 38,980 kB
  • sloc: cpp: 123,583; ansic: 66,779; python: 8,358; java: 6,406; fortran: 6,079; f90: 5,123; xml: 4,587; sh: 2,337; perl: 1,436; makefile: 105; lisp: 49; javascript: 7; sed: 6
file content (84 lines) | stat: -rw-r--r-- 3,118 bytes parent folder | download
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# Copyright (c) 2010-2025. The SimGrid Team. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the license (GNU LGPL) which comes with this package.

import sys

from simgrid import Engine, Actor, ActivitySet, Comm, NetZone, Link, LinkInRoute, Mailbox, this_actor, NetworkFailureException


def sender(mailbox1_name: str, mailbox2_name: str) -> None:
    mailbox1: Mailbox = Mailbox.by_name(mailbox1_name)
    mailbox2: Mailbox = Mailbox.by_name(mailbox2_name)

    this_actor.info(f"Initiating asynchronous send to {mailbox1.name}")
    comm1: Comm = mailbox1.put_async(666, 5)

    this_actor.info(f"Initiating asynchronous send to {mailbox2.name}")
    comm2: Comm = mailbox2.put_async(666, 2)

    this_actor.info("Calling wait_any..")
    pending_comms = ActivitySet([comm1, comm2])
    try:
        comm = pending_comms.wait_any()
        this_actor.info(f"Wait any returned a comm to {comm.mailbox.name})")
    except NetworkFailureException:
        this_actor.info("Sender has experienced a network failure exception, so it knows that something went wrong")
        this_actor.info("Now it needs to figure out which of the two comms failed by looking at their state:")

    this_actor.info(f"  Comm to {comm1.mailbox.name} has state: {comm1.state_str}")
    this_actor.info(f"  Comm to {comm2.mailbox.name} has state: {comm2.state_str}")

    try:
        comm1.wait()
    except NetworkFailureException as err:
        this_actor.info(f"Waiting on a FAILED comm raises an exception: '{err}'")

    this_actor.info("Wait for remaining comm, just to be nice")
    try:
        pending_comms.wait_all()
    except Exception as e:
        this_actor.warning(str(e))


def receiver(mailbox_name: str) -> None:
    mailbox: Mailbox = Mailbox.by_name(mailbox_name)
    this_actor.info(f"Receiver posting a receive ({mailbox_name})...")
    try:
        mailbox.get()
        this_actor.info(f"Receiver has received successfully ({mailbox_name})!")
    except NetworkFailureException:
        this_actor.info(f"Receiver has experience a network failure exception ({mailbox_name})")


def link_killer(link_name: str) -> None:
    link_to_kill = Link.by_name(link_name)
    this_actor.sleep_for(10.0)
    this_actor.info(f"Turning off link '{link_to_kill.name}'")
    link_to_kill.turn_off()

def main():
    e = Engine(sys.argv)
    zone: NetZone = e.netzone_root
    host1 = zone.add_host("Host1", "1f")
    host2 = zone.add_host("Host2", "1f")
    host3 = zone.add_host("Host3", "1f")

    link_to_2 = zone.add_link("link_to_2", "1bps").seal()
    link_to_3 = zone.add_link("link_to_3", "1bps").seal()

    zone.add_route(host1, host2, [link_to_2])
    zone.add_route(host1, host3, [link_to_3])
    zone.seal()

    e.add_actor("Sender", host1, sender, "mailbox2", "mailbox3")
    e.add_actor("Receiver-1", host2, receiver, "mailbox2").daemonize()
    e.add_actor("Receiver-2", host3, receiver, "mailbox3").daemonize()
    e.add_actor("LinkKiller", host2, link_killer, "link_to_2").daemonize()

    e.run()


if __name__ == "__main__":
    main()