Aluno: Leonardo Bueno Nogueira Kruger GRR: 20180130
Aluno: Lucas Block Villatore GRR: 20171677
- Você tem 3 servidores de temperatura em lugares extremos do mundo: ou normalmente muito frios ou normalmente muito quentes. Cada um destes servidores recebem uma resposta e simplemente mandam uma resposta com um número inteiro que mais se aproxima da temperatura medida.
- Um cliente não acessa os servidores individualmente, e sim uma cache que mantém os últimos valores recebidos dos 3 servidores. Assim evitamos que o cliente tenha que fazer 3 acessos muito distantes, para fazer 1 acesso mais próximo.
- A cache mantém uma tabela cache com os dados, com um prazo de validade para cada entrada de 30 segundos. Implemente o cliente. Implemente também a tabela cache da maneira eficiente que foi apresentada em sala de aula. Quando chega uma requisição e algum valor expirou, deve ser feita nova consulta ao servidor original.
- Para os 3 servidores, a dupla pode tanto implementá-los como servidores do trabalho, utilizando número aleatórios dentro de uma faixa razoável para os valores de temperatura ou, alternativamente, obter as informações adequadamente na Web.
- Devem ser apresentados logs para múltiplas execuções. Mostre com clareza situações em que uma requisição de usuário encontra/não encontra a cache com informações válidas.
Linguagem de programação: Python
Conforme a descrição do trabalho, existem três servidores que:
- Ao receber uma requisição
- Mandam uma resposta com um número representando sua temperatura, para melhorar a dinamica do projeto cada servidor possui um range de temperatura para retornar.
def get_temperature(): # Função que retorna temperatura do servidor
print("Checking temperature on server 1")
time.sleep(randrange(5))
return randrange(30) - 6
if __name__ == "__main__":
connection, address = create_connection(HOST, PORT)
print("Connected by {}".format(address))
while True:
data = connection.recv(MESSAGE_SIZE_IN_BYTES) # 1. Recebe requisição/conexão
temperature = get_temperature()
print("Temperature on server 3 is {}".format(temperature))
connection.sendall(str(temperature).encode("utf-8")) # 2. Envia a resposta
Na cache é mantido a tabela dos dados de temperatura dos servidores e o prazo de validade para cada entrada e em caso de requisição retorna os valores guardados se estiverem validos ou faz uma nova consulta caso contrario.
- É estabelicida conexão com cada servidor, e salvo na estrutura servers[]
- Em seguida é inicializada a tabela cache com uma linha para cada servidor ( ainda sem valores dos servidores ).
- Cria conexão da Cache, escutando no HOST e PORT especificados.
- Ao receber uma nova conexão;
- Para cada linha na tabela;
- Realiza a checagem de validez dos dados;
- Se invalido faz uma requisição para atualizar pegar os valores.
- Se valido pega os valores da tabela cache
- Envia a resposta da requisição.
if __name__ == "__main__":
# 1. Cria conexão com servidores
servers = []
print("Establishing connection with server 1")
servers.append(make_connection_to_server(HOST_1, PORT_1))
print("Establishing connection with server 2")
servers.append(make_connection_to_server(HOST_2, PORT_2))
print("Establishing connection with server 3")
servers.append(make_connection_to_server(HOST_3, PORT_3))
# 2. Inicializa tabela cache
CACHE_TABLE = init_cache_table(servers)
# 3. Inicializa conexão cache (cache listen on cache host, port)
connection, address = create_connection(CACHE_HOST, CACHE_PORT)
print("Connected by {}".format(address))
while(True):
# 4. Recebe nova conexão
data = connection.recv(MESSAGE_SIZE_IN_BYTES)
temperature_from_servers = []
# 5. Para cada linha na tabela cache
for cache_row in CACHE_TABLE:
is_from_cache = True
# 6. Checagem se o valor é valido
if already_expired_cache_server_row(cache_row):
is_from_cache = False
print("Cache from {} is expired, requesting a new temperature".format(cache_row.get("server_name")))
# 7. Se invalido faz uma requisição para atualizar pegar os valores
cache_row = request_temperature_from_server(cache_row)
print("Updating row {} from cache table".format(cache_row.get("server_name")))
update_cache_table(cache_row)
else:
# 8. Se valido pega os valores da tabela cache
print("Cache from {} stil valid, getting temperature from cache".format(cache_row.get("server_name")))
print()
temperature_from_servers.append({
"temperature": cache_row.get("temperature"),
"is_from_cache": is_from_cache,
"server_name": cache_row.get("server_name")
})
# 9. Retorna os valores
connection.sendall(str(json.dumps(temperature_from_servers)).encode("utf-8"))
time.sleep(5)
No cliente é executado a requisição das temperaturas dos servidores para a cache.
- É estabelecida conexão com a cache.
- Envia a requisição;
- Recebe a resposta;
- Print dos resultados
def make_connection_to_server(host, port):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((host, port))
time.sleep(1)
return client
def print_result(temperature_informations):
is_from_cache = "WAS" if temperature_informations.get("is_from_cache") else "WAS NOT"
temperature = temperature_informations.get("temperature")
server = temperature_informations.get("server_name")
print("Temperature on {} is {} and {} received from cache".format(server, temperature, is_from_cache))
if __name__ == '__main__':
pass
# 1. Cria conexão com cache
client = make_connection_to_server(CACHE_HOST, CACHE_PORT)
while True:
# 2. Envia requisição para cache
client.sendall(b"Get temperature")
# 3. Recebe resposta
temperatures = client.recv(MESSAGE_SIZE_IN_BYTES)
temperatures = json.loads(temperatures.decode("utf-8"))
# 4. Print resposta
for temperature in temperatures:
print_result(temperature)
print()
Digite os seguintes comandos no terminal
Cada comando deve ser executado em um próprio terminal
$ python3 servidor1.py
$ python3 servidor2.py
$ python3 servidor3.py
$ python3 cache.py
$ python3 cliente.py