Academic Reference

Distributed Systems

Practical Run Guide & Code Reference

Package snipx-ds Version 0.1.0 Practicals 6 Language Python 3

Table of Contents

  1. Practical 1 — Multi-threaded RMI (XML-RPC)
  2. Practical 2 — CORBA Object Brokering (Pyro5)
  3. Practical 3 — Distributed Sum (MPI / OpenMP Simulation)
  4. Practical 4 — Berkeley Clock Synchronization
  5. Practical 5 — Token Ring Mutual Exclusion
  6. Practical 6 — Leader Election (Bully + Ring)
  7. Quick-Reference Summary
P1

Multi-threaded RMI (XML-RPC)

What This Practical Does

Simulates Java Remote Method Invocation (RMI) using Python's built-in xmlrpc module. A custom threaded server spawns a new thread for each client connection, allowing multiple clients to invoke remote calculator methods concurrently. Five client threads run in parallel, each calling add, subtract, multiply, divide, and echo on the same server.

Files & Their Roles
FileRole
server.pyThreaded XML-RPC server — registers RemoteCalculator and handles each client in its own thread
client.pySpawns 5 concurrent client threads, each invoking all remote methods via ServerProxy
Tools / Software Required
🪟 Windows
# Python 3.8+ required (xmlrpc is in the standard library)
winget install Python.Python.3.11   # or download from python.org
# No extra pip packages needed
🐧 Linux
sudo apt update && sudo apt install python3 python3-pip
# No extra pip packages needed
Step-by-Step Run Instructions
  1. 1

    Get the files with dsnip get p1 — they appear in ./ds_code/p1/.

    🪟 Windows
    dsnip get p1
    cd ds_code\p1
    🐧 Linux
    dsnip get p1
    cd ds_code/p1
  2. 2

    Open Terminal 1 and start the server.

    🪟 Windows — Terminal 1
    python server.py
    🐧 Linux — Terminal 1
    python3 server.py
  3. 3

    Open Terminal 2 and run the multi-threaded client.

    🪟 Windows — Terminal 2
    python client.py
    🐧 Linux — Terminal 2
    python3 client.py
  4. 4

    Press Ctrl+C in Terminal 1 to stop the server.

Expected Output (client terminal)
[Client-1] Connected to RMI server at http://localhost:8000
[Client-1] add(10, 5) = 15
[Client-2] subtract(100, 6) = 94
[Client-3] multiply(3, 7) = 21
[Client-4] divide(100, 4) = 25.00
[Client-5] echo → 'Server echoes: Hello from client 5'
[Main] All client threads finished.
P2

CORBA Object Brokering (Pyro5)

What This Practical Does

Simulates CORBA (Common Object Request Broker Architecture) using Pyro5 (Python Remote Objects). A Name Server acts as the broker (CosNaming), the server registers a CalculatorServant object with it, and the client resolves the logical name corba.calculator to get a transparent proxy (stub). All method calls cross the network with full location transparency.

Files & Their Roles
FileRole
server.pyServant object — registers CalculatorServant with the Name Server as corba.calculator
client.pyStub/proxy client — resolves the name, creates a Pyro5 proxy, invokes arithmetic and string methods
Tools / Software Required
🪟 Windows
winget install Python.Python.3.11
pip install Pyro5
🐧 Linux
sudo apt install python3 python3-pip
pip3 install Pyro5
Step-by-Step Run Instructions
Three terminals are required — start them in order.
  1. 1

    Get the files.

    🪟 Windows
    dsnip get p2
    cd ds_code\p2
    🐧 Linux
    dsnip get p2
    cd ds_code/p2
  2. 2

    Terminal 1 — Start the Pyro5 Name Server (broker).

    🪟 Windows — Terminal 1
    python -m Pyro5.nameserver
    🐧 Linux — Terminal 1
    python3 -m Pyro5.nameserver
  3. 3

    Terminal 2 — Start the Calculator Servant.

    🪟 Windows — Terminal 2
    python server.py
    🐧 Linux — Terminal 2
    python3 server.py
  4. 4

    Terminal 3 — Run the client.

    🪟 Windows — Terminal 3
    python client.py
    🐧 Linux — Terminal 3
    python3 client.py
Expected Output (client terminal)
[ORB] Name Server located.
[ORB] Resolved 'corba.calculator' → PYRO:obj_...
[Client] Proxy (stub) created

── Arithmetic Operations ──
  add(15, 7)       = 22
  multiply(6, 9)   = 54
  power(2, 10)     = 1024.0

── String Operations ──
  string_reverse('CORBA') = ABROC

── Error Handling Demo ──
  divide(10, 0) raised: ValueError: Division by zero
P3

Distributed Sum (MPI / OpenMP Simulation)

What This Practical Does

Simulates MPI-style distributed computation using Python's multiprocessing module. An array of N elements is divided into N/n chunks and distributed to n worker processes (MPI ranks). Each worker computes a partial (intermediate) sum of its chunk, and the master gathers and adds them to produce the final sum.

Files & Their Roles
FileRole
distributed_sum.pyMaster + worker processes — implements scatter, parallel summation, and gather phases
Tools / Software Required
🪟 Windows
winget install Python.Python.3.11
# No extra packages — uses built-in multiprocessing
🐧 Linux
sudo apt install python3
# No extra packages
Step-by-Step Run Instructions
  1. 1
    🪟 Windows
    dsnip get p3
    cd ds_code\p3
    python distributed_sum.py
    🐧 Linux
    dsnip get p3
    cd ds_code/p3
    python3 distributed_sum.py
  2. 2

    To customize, edit the bottom of distributed_sum.py:

    distributed_sum(N=20, num_processors=4)           # random array
    distributed_sum(N=15, num_processors=3, array=[...]) # custom array
Expected Output
Total elements  (N)          : 20
Number of processors (n)     : 4
Elements per processor (N/n) : ~5

  [Processor-0] Assigned elements : [12, 45, 3, 67, 8]
  [Processor-0] Intermediate sum  : 135
  [Processor-1] Intermediate sum  : 193
  ...

  Final Distributed Sum = 947
  Direct Sum (verify)   = 947
  Match: [OK] CORRECT
P4

Berkeley Clock Synchronization

What This Practical Does

Implements the Berkeley Algorithm — a master-slave clock synchronization protocol that does not rely on an external time source (unlike NTP). The master polls all slave clocks, computes the average time, calculates a per-node adjustment delta, and broadcasts corrections. All clocks converge to a synchronized average.

Files & Their Roles
FileRole
berkeley_clock_sync.pyComplete simulation — ClockNode with skew, BerkeleyMaster that polls, averages, and sends deltas
Tools / Software Required
🪟 Windows
winget install Python.Python.3.11   # No extra packages
🐧 Linux
sudo apt install python3   # No extra packages
Step-by-Step Run Instructions
  1. 1
    🪟 Windows
    dsnip get p4
    cd ds_code\p4
    python berkeley_clock_sync.py
    🐧 Linux
    dsnip get p4 && cd ds_code/p4
    python3 berkeley_clock_sync.py
Expected Output
--- Before Synchronization ---
  Master     skew=+2.341s  local_time=...
  Slave-1    skew=-7.823s  local_time=...

Clock spread before sync : 14.2310 seconds

Step 1: Master polls all slave clocks
Step 2: Master computes average time = ...
Step 3: Master sends adjustment deltas
   Master      adjustment: +1.2300s
   Slave-1     adjustment: -2.1100s

--- After Synchronization ---
Clock spread after sync  : 0.000001 seconds
Improvement              : 14231.0x reduction in skew
[OK] Berkeley synchronization complete.
P5

Token Ring Mutual Exclusion

What This Practical Does

Implements the Token Ring algorithm for mutual exclusion using Python threads. Processes are arranged in a logical ring (P0→P1→…→Pn→P0). A single TOKEN circulates; only the token-holder may enter its Critical Section (CS). Guarantees: mutual exclusion, no deadlock, no starvation, and fair round-robin access.

Files & Their Roles
FileRole
token_ring.pyRingProcess (one thread/node) + coordinator that injects the initial token and collects stats
Tools / Software Required
🪟 Windows
winget install Python.Python.3.11   # uses built-in threading + queue
🐧 Linux
sudo apt install python3   # no extra packages
Step-by-Step Run Instructions
  1. 1
    🪟 Windows
    dsnip get p5
    cd ds_code\p5
    python token_ring.py
    🐧 Linux
    dsnip get p5 && cd ds_code/p5
    python3 token_ring.py
  2. 2

    To change ring size or rounds, edit the last line:

    run_token_ring(num_processes=5, num_rounds=3)
Expected Output
Ring layout: P0 -> P1 -> P2 -> P3 -> P4 -> P0

  [Process-0] received TOKEN
  [Process-0] ENTERING  Critical Section [**]
  [Process-0] EXITING   Critical Section (CS count = 1)
  [Process-0] passing TOKEN -> P1
  [Process-1] received TOKEN
  [Process-1] has no CS request - passing token immediately
  ...
--- Simulation Summary ---
  Process-0: entered Critical Section 2 time(s)
  Mutual Exclusion : [OK] Guaranteed
P6

Leader Election (Bully + Ring)

What This Practical Does

Implements two classic leader election algorithms:

  • Bully Algorithm — the process with the highest ID always wins (O(n²) messages).
  • Ring Algorithm — election message travels clockwise; the highest ID in the ring wins (O(n) messages).

The coordinator crashes, a surviving process detects the failure and starts an election, and a new leader is elected via each algorithm.

Files & Their Roles
FileRole
main.pyRunner — executes Bully then Ring algorithm back-to-back
bully_algorithm.pyBully election: BullyProcess + BullyElection classes
ring_algorithm.pyRing election: RingElectionProcess + RingElection classes
Tools / Software Required
🪟 Windows
winget install Python.Python.3.11   # no extra packages
🐧 Linux
sudo apt install python3   # no extra packages
Step-by-Step Run Instructions
All three files must be in the same directory — dsnip get p6 handles this automatically.
  1. 1
    🪟 Windows
    dsnip get p6
    cd ds_code\p6
    python main.py
    🐧 Linux
    dsnip get p6 && cd ds_code/p6
    python3 main.py
  2. 2

    Run algorithms individually (optional):

    🪟 Windows
    python bully_algorithm.py
    python ring_algorithm.py
    🐧 Linux
    python3 bully_algorithm.py
    python3 ring_algorithm.py
Expected Output
*** PART A: BULLY ALGORITHM ***
Processes: [Process-0[UP], Process-1[UP], ..., Process-5[UP]]
Initial Coordinator: Process-5
-- Coordinator Process-5 CRASHES --
-- Election started by Process-2 --
Process-2 sends ELECTION to: [3, 4]
  -> Process-3 receives ELECTION ... OK
  -> Process-4 receives ELECTION ... OK
[ELECTED] Process-4 declares itself COORDINATOR

*** PART B: RING ALGORITHM ***
Ring: P0 -> P1 -> P2 -> P3 -> P4 -> P5 -> P0
-- Coordinator Process-5 CRASHES --
-- Ring Election started by Process-2 --
  -> Process-3 (higher ID, adds itself): ELECTION[2, 3]
  -> Process-4 (higher ID, adds itself): ELECTION[2, 3, 4]
Winner (highest ID): Process-4
[OK] Ring election complete. New leader: Process-4

Quick-Reference Summary

KeyPractical #TitleFilesDependenciesRun Command
p11 Multi-threaded RMI server.py client.py None (stdlib) python server.py + python client.py
p22 CORBA Object Brokering server.py client.py pip install Pyro5 3 terminals (nameserver → server → client)
p33 Distributed Sum (MPI) distributed_sum.py None (stdlib) python distributed_sum.py
p44 Berkeley Clock Sync berkeley_clock_sync.py None (stdlib) python berkeley_clock_sync.py
p55 Token Ring Mutex token_ring.py None (stdlib) python token_ring.py
p66 Leader Election main.py bully_algorithm.py ring_algorithm.py None (stdlib) python main.py
CLI Quick Reference
pip install snipx-ds          # install the package
dsnip help                    # show all commands
dsnip list                    # list all practicals
dsnip list python             # filter by language
dsnip get p1                  # copy Practical 1 files → ./ds_code/p1/
dsnip get p6                  # copy Practical 6 files → ./ds_code/p6/
dsnip guide                   # open this guide in browser