-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathload_balancer.py
More file actions
159 lines (126 loc) · 4.54 KB
/
load_balancer.py
File metadata and controls
159 lines (126 loc) · 4.54 KB
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
147
148
149
150
151
152
153
154
155
156
157
158
159
"""
O desafio é manter os servidores o mais ocupados quanto é possível até um certo limite de capacidade. Em nosso ambiente de simulação cada tick de relógio (unidade de tempo) um certo número de usuários se conectam a servidores disponíveis e requisitam uma mesma tarefa a ser executada.
Cada tarefa consome Ttask ticks de tempo para ser executada e depois disso o usuário se desconecta imediatamente. Os servidores são máquinas virtuais que podem ser iniciadas instantaneamente para atender novos usuários. Cada servidor custa $1.00 por tick de relógio e consegue lidar com um número Umax de usuários simultaneos.
Você pode desligar servidores vazios, isso é, sem tarefas sendo executadas. Seu desafio é construir um programa em Python que lide com usuários acessando o sistema assinalando suas tarefas de forma que o custo de servidores ligados seja o minimo possível.
Entrada: Um arquivo que apresenta em cada linha o número de novos usuários acessando o sistema. Saída: Um arquivo em que cada linha contenha uma lista de servidores disponíveis ao final do tick representado o número de usuários conectados em cada servidor. Exemplo com Ttask = 4 e Umax = 2:
# Clock Ticks
# Input
# Output
# Tip
# 1
# 1
# 1
# 1 server for 1 user. (1 server created)
# 2
# 3
# 2,2
# 2 servers for 4 users. (1 server created)
# 3
# 0
# 2,2
# idem
# 4
# 1
# 2,2,1
# 3 servers for 5 users. (1 server created)
# 5
# 0
# 1,2,1
# 3 servers for 4 users. (First user left after 4 ticks)
# 6
# 1
# 2
# 1 server for 2 users (3 users left, 1 joined. 2 servers terminated)
"""
import time
TTAKS = 4
UMAX = 2
class LoadBalance:
r"""
>>> lb = LoadBalance([], max_users=2)
>>> lb.get_status()
'\n0 servers for 0 users. (0 servers created)'
>>> lb.add_user(Task(4))
>>> lb.get_status()
'1\n1 servers for 1 users. (1 servers created)'
>>> lb.tick()
>>> lb.add_user(Task(4))
>>> lb.add_user(Task(4))
>>> lb.add_user(Task(4))
>>> lb.get_status()
'2, 2\n2 servers for 4 users. (1 servers created)'
>>> lb.tick()
>>> lb.get_status()
'2, 2\n2 servers for 4 users. (0 servers created)'
>>> lb.tick()
>>> lb.add_user(Task(4))
>>> lb.get_status()
'2, 2, 1\n3 servers for 5 users. (1 servers created)'
>>> lb.tick()
>>> lb.get_status()
'1, 2, 1\n3 servers for 4 users. (0 servers created)'
>>> lb.tick()
>>> lb.add_user(Task(4))
>>> lb.get_status()
'2\n1 servers for 2 users. (0 servers created)'
>>> lb.tick()
"""
server_created_this_tick = 0
def __init__(self, *servers, max_users):
self.servers = list(*servers)
self.max_users = max_users
def add_server(self, server):
self.servers.append(server)
self.server_created_this_tick += 1
def get_free_server(self):
for server in self.servers:
if len(server.users) < self.max_users:
break
else:
server = Server([], max_users=UMAX)
self.add_server(server)
return server
def get_status(self):
total_servers = 0
total_users = 0
users_status = []
for server in self.servers:
total_servers += 1
total_users += len(server.users)
users_status.append(len(server.users))
# users_status = ', '.join(map(str, users_status)) # Menos legivel
users_status = str(users_status)[1:-1]
return f"{users_status}\n{total_servers} servers for {total_users} users. ({self.server_created_this_tick} servers created)"
def add_user(self, user):
server = self.get_free_server()
server.add_user(user)
def tick(self):
self.server_created_this_tick = 0
for server in self.servers:
server.tick()
self.servers = list(filter(lambda server:server.users != [], self.servers))
class Server:
def __init__(self, *users, max_users):
self.max_users = max_users
self.users = list(*users)[:max_users]
def add_user(self, user):
self.users.append(user)
def tick(self):
for user in self.users:
user.tick()
self.users = list(filter(lambda user:user.ttask != 0, self.users))
class Task:
def __init__(self, ttask):
self.ttask = ttask
def tick(self):
self.ttask -= 1
if __name__ == "__main__":
lb = LoadBalance([], max_users=UMAX)
schedule = [1, 3, 0, 1, 0, 1]
for i in schedule:
for j in range(i):
lb.add_user(Task(TTAKS))
print(lb.get_status())
print('Tick!')
lb.tick()
time.sleep(1)