Skip to content

Commit 34f4bba

Browse files
committed
Added tut 10
1 parent e90b799 commit 34f4bba

File tree

5 files changed

+54
-30
lines changed

5 files changed

+54
-30
lines changed

README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,18 @@ Later we will get onto more complicated topics such as reaching a consensus of w
1414

1515
Questions comments and suggestions can be raised the specific blog post or by using issues here.
1616

17-
## Tutorial 9 - Multi Slave Master
17+
## Tutorial 10 - More Advanced Connection Handling
1818

19-
This tutorial focuses on changing the master so that it accepts
20-
multiple slaves connecting to it.
19+
This tutorial focuses on improving the master and slaves connection
20+
handling code. Here I am going to add a custom exception that can
21+
be used in the event of disconnection.
2122

22-
Currently there is no error handling for nodes connecting and disconnecting.
23-
The next tutorial will focus on hardening the master and slaves connection/disconnection code.
23+
In the next tutorial we will look at improving the slave so that if
24+
the master goes down, it will rejoin at the next opportunity.
2425

2526
The full details for
26-
[Tutorial 09 - Multi Slave Master is available on my blog](
27-
https://chewett.co.uk/blog/1872/raspberry-pi-cluster-node-09-multi-slave-master/
27+
[Tutorial 10 - More Advanced Connection Handling is available on my blog](
28+
https://chewett.co.uk/blog/1913/raspberry-pi-cluster-node-10-more-advanced-connection-handling/
2829
)
2930

3031
## Requirements

RpiCluster/DataPackager.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import socket
22
import json
3+
from RpiClusterExceptions import DisconnectionException
34

45
MESSAGE_SEPARATOR = "\r"
56

@@ -42,7 +43,8 @@ def get_message(clientsocket):
4243
try:
4344
data = clientsocket.recv(512) #Get at max 512 bytes of data from the client
4445
except socket.error: #If we failed to get data, assume they have disconnected
45-
return None
46+
raise DisconnectionException("Failed to receive messages, client has disconnected")
47+
4648
data_len = len(data)
4749
if data_len > 0: #Do something if we got data
4850
_buffered_string += data #Keep track of our buffered stored data
@@ -52,4 +54,13 @@ def get_message(clientsocket):
5254
if message_in_buffer:
5355
return message_in_buffer
5456
else:
55-
return None
57+
raise DisconnectionException("No further messages received, client has disconnected")
58+
59+
60+
def send_message(clientsocket, payload):
61+
try:
62+
clientsocket.send(payload)
63+
return True
64+
except socket.error:
65+
raise DisconnectionException("Failed to send message")
66+

RpiCluster/RpiClusterClient.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import json
22
import threading
3-
from DataPackager import get_message, create_payload
3+
import time
4+
from DataPackager import get_message, create_payload, send_message
5+
from RpiClusterExceptions import DisconnectionException
46
from MachineInfo import get_base_machine_info
57
from MainLogger import logger
68

@@ -13,21 +15,20 @@ def __init__(self, clientsocket, address):
1315
self.address = address
1416

1517
def run(self):
16-
message = True
17-
while message:
18-
message = get_message(self.clientsocket)
19-
if message:
18+
try:
19+
message = True
20+
while message:
21+
message = get_message(self.clientsocket)
2022
if message['type'] == 'message':
2123
logger.info("Received message: " + message['payload'])
2224
elif message['type'] == 'computer_details':
2325
logger.info("Computer specifications: " + json.dumps(message['payload']))
2426
elif message['type'] == 'info':
2527
logger.info("Slave wants to know my info about " + message['payload'])
2628
if message['payload'] == 'computer_details':
27-
self.clientsocket.send(create_payload(get_base_machine_info(), "master_info"))
29+
send_message(self.clientsocket, create_payload(get_base_machine_info(), "master_info"))
2830
else:
29-
self.clientsocket.send(create_payload("unknown", "bad_message"))
30-
31-
else:
32-
logger.info("Client disconnected at address {addr}".format(addr=self.address))
33-
31+
send_message(self.clientsocket, create_payload("unknown", "bad_message"))
32+
except DisconnectionException as e:
33+
logger.info("Got disconnection exception with message: " + e.message)
34+
logger.info("Shutting down slave connection handler")

RpiCluster/RpiClusterExceptions.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
3+
class DisconnectionException(Exception):
4+
pass
5+

basic_slave.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
import socket
77
import json
88
from RpiCluster.MainLogger import add_file_logger, logger
9-
from RpiCluster.DataPackager import create_payload, get_message
9+
from RpiCluster.DataPackager import create_payload, get_message, send_message
1010
from RpiCluster.MachineInfo import get_base_machine_info
11+
from RpiCluster.RpiClusterExceptions import DisconnectionException
1112

1213
config = ConfigParser.ConfigParser()
1314
config.read('rpicluster.cfg')
@@ -27,14 +28,19 @@
2728

2829
client_number = random.randint(1, 100000)
2930

30-
logger.info("Sending an initial hello to master")
31-
sock.send(create_payload(get_base_machine_info(), 'computer_details'))
32-
sock.send(create_payload("computer_details", "info"))
31+
try:
32+
logger.info("Sending an initial hello to master")
33+
send_message(sock, create_payload(get_base_machine_info(), 'computer_details'))
34+
send_message(sock, create_payload("computer_details", "info"))
3335

34-
message = get_message(sock)
35-
logger.info("We have information about the master " + json.dumps(message['payload']))
36+
message = get_message(sock)
37+
logger.info("We have information about the master " + json.dumps(message['payload']))
3638

37-
while True:
38-
logger.info("Now sending a keepalive to the master")
39-
sock.send(create_payload("I am still alive, client: {num}".format(num=client_number)))
40-
time.sleep(5)
39+
while True:
40+
logger.info("Now sending a keepalive to the master")
41+
send_message(sock, create_payload("I am still alive, client: {num}".format(num=client_number)))
42+
time.sleep(5)
43+
44+
except DisconnectionException as e:
45+
logger.info("Got disconnection exception with message: " + e.message)
46+
logger.info("Shutting down slave")

0 commit comments

Comments
 (0)