-
Notifications
You must be signed in to change notification settings - Fork 1
/
participant_subservice.cpp
146 lines (125 loc) · 4.32 KB
/
participant_subservice.cpp
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#pragma once
#include <iostream>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <net/if.h>
#include <stdlib.h>
#include "socket.cpp"
#include "information_subservice.cpp"
#include "election_subservice.cpp"
#include "discovery_subservice.cpp"
#define PORT 4000
#define EXIT_PORT 4001
#define KEEPALIVE_PORT 4002
#define MAX_MISSED_KEEPALIVES 3
#define MAX_MISSED_DISCOVERY 10
#define KEEPALIVE_INTERVAL 1
#define BROADCAST_IP "255.255.255.255"
using namespace std;
string manager_ip = "", manager_mac = "", manager_hostname = "";
bool manager_changed = false;
extern bool manager;
bool keep_monitoring = true;
void becomeManager(){
manager = true;
}
void listenForServicePackets() {
Socket ptcp_socket;
int send_res, recv_res;
string mac_addr = getMacAddress();
string hostname = getSelfHostname();
cerr << "Entrando na listenForServicePackets" << endl;
// ptcp_socket.setTimeoutOpt();
ptcp_socket.listenPort(PORT);
while(true) {
// if (manager) {
// continue;
// }
// Listen for packets sent by the manager to PORT
recv_res = ptcp_socket.receiveMessage();
if (recv_res > 0) {
// cerr << "[P] Manager (IP " << ptcp_socket.getSenderIP() << ") asked: " << ptcp_socket.getBuffer() << endl;
// Get manager infos
string received_ip = ptcp_socket.getSenderIP();
string buffer = ptcp_socket.getBuffer();
string received_mac = buffer.substr(0,17);
string received_hostname = buffer.substr(17);
if (manager && received_ip != getSelfIP()) {
// cerr << received_ip << " is another manager" << endl;
// manager = false;
// startManagerElection();
}
if (manager_ip != received_ip || manager_mac != received_mac || manager_hostname != received_hostname) {
manager_ip = received_ip;
manager_mac = received_mac;
manager_hostname = received_hostname;
manager_changed = true;
}
// Answers the packet received
send_res = ptcp_socket.sendMessageToSender(mac_addr + hostname);
if (send_res < 0)
cerr << "[P] ERROR sendto" << endl;
}
}
ptcp_socket.closeSocket();
cerr << "[P] Exiting listenForServicePackets thread" << endl;
}
void monitorateManagerStatus() {
Socket ptcp_socket, ptcp_socket2;
int send_res, recv_res, missed_keepalives = 0, manager_discovery_count = 0;
string mac_addr = getMacAddress();
string hostname = getSelfHostname();
// Wait for the discovery of a manager
while(manager_ip == "" && !manager) {
// cout << "[P] Manager not known yet" << endl;
manager_discovery_count++;
cerr << "[P] Manager not found. Count: " << manager_discovery_count << endl;
if(manager_discovery_count >= MAX_MISSED_DISCOVERY) {
startManagerElection();
MachinesManager::Instance().createMachine(getSelfIP(), mac_addr, hostname);
MachinesManager::Instance().setNewManager(getSelfIP());
addParticipantsFromTable();
}
sleep(1);
}
while(true) {
if (manager) {
continue;
}
missed_keepalives = 0;
while(keep_monitoring) {
ptcp_socket.setSendAddr(manager_ip, KEEPALIVE_PORT);
// Send packet querying the manager's status
send_res = ptcp_socket.sendMessage(mac_addr + hostname);
if (send_res < 0)
cerr << ("[P] ERROR sendto") << endl;
recv_res = ptcp_socket.receiveMessage();
if (recv_res < 0) {
missed_keepalives++;
cerr << "[P] Manager didn't answer. Missed keepalives: " << missed_keepalives << endl;
if (missed_keepalives >= MAX_MISSED_KEEPALIVES) {
// ptcp_socket2.setBroadcastOpt();
// ptcp_socket2.setSendAddr(BROADCAST_IP, PORT);
// cout << "[P] Starting a Manager election" << endl;
startManagerElection();
// if (newManager == true) {becomeManager()} // IDEA
keep_monitoring = false;
}
}
else {
// cout << "[P] Manager " << IP << " answered: " << ptcp_socket.getBuffer() << endl;
missed_keepalives = 0;
}
sleep(KEEPALIVE_INTERVAL);
}
}
ptcp_socket.closeSocket();
cerr << "[P] Exiting monitorateManagerStatus thread" << endl;
}
void sendExitPacket(){
Socket exit_socket;
exit_socket.setSendAddr(manager_ip, EXIT_PORT);
//Send exit message to specified exit port
int exit_message = exit_socket.sendMessage("sleep service exit");
}