Skip to content

Commit 19de94a

Browse files
committed
feat[fallback]!: add option to mark servers as fallbacks
1 parent 2125bd6 commit 19de94a

File tree

6 files changed

+87
-24
lines changed

6 files changed

+87
-24
lines changed

controller/src/controller/group.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use super::{
2020

2121
const GROUPS_DIRECTORY: &str = "groups";
2222

23-
type GroupHandle = Arc<Group>;
23+
pub type GroupHandle = Arc<Group>;
2424
pub type WeakGroupHandle = Weak<Group>;
2525

2626
pub struct Groups {

controller/src/controller/server.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,21 @@ impl Servers {
304304
}
305305
}
306306

307+
pub fn find_fallback_server(&self, excluded: &ServerHandle) -> Option<ServerHandle> {
308+
// TODO: Also check if the server have free slots
309+
self.servers
310+
.lock()
311+
.unwrap()
312+
.iter()
313+
.filter(|server| {
314+
!Arc::ptr_eq(server, excluded)
315+
&& server.allocation.deployment.fallback.enabled
316+
&& *server.state.lock().unwrap() == State::Running
317+
})
318+
.max_by_key(|server| server.allocation.deployment.fallback.priority)
319+
.cloned()
320+
}
321+
307322
fn start_server(
308323
&self,
309324
request: &StartRequestHandle,
@@ -458,6 +473,12 @@ pub enum Retention {
458473
Permanent,
459474
}
460475

476+
#[derive(Serialize, Deserialize, Clone, Default)]
477+
pub struct FallbackPolicy {
478+
pub enabled: bool,
479+
pub priority: i32,
480+
}
481+
461482
#[derive(Serialize, Deserialize, Clone)]
462483
pub struct KeyValue {
463484
pub key: String,
@@ -470,4 +491,6 @@ pub struct Deployment {
470491
pub environment: Vec<KeyValue>,
471492
pub disk_retention: Retention,
472493
pub image: String,
494+
495+
pub fallback: FallbackPolicy,
473496
}

controller/src/controller/user.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,23 @@ impl Users {
106106
amount
107107
}
108108

109+
pub fn get_users_on_server(&self, server: &ServerHandle) -> Vec<UserHandle> {
110+
self.users
111+
.lock()
112+
.unwrap()
113+
.values()
114+
.filter(|user| {
115+
if let CurrentServer::Connected(weak_server) = user.server.lock().unwrap().deref() {
116+
if let Some(strong_server) = weak_server.upgrade() {
117+
return Arc::ptr_eq(&strong_server, server);
118+
}
119+
}
120+
false
121+
})
122+
.cloned()
123+
.collect()
124+
}
125+
109126
fn create_user(&self, name: String, uuid: Uuid, server: &ServerHandle) -> UserHandle {
110127
Arc::new(User {
111128
name,

controller/src/controller/user/transfer.rs

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,36 @@ use log::error;
44
use log::info;
55
use log::warn;
66

7+
use crate::controller::group::GroupHandle;
78
use crate::controller::{
89
event::{transfer::UserTransferRequested, EventKey},
9-
group::WeakGroupHandle,
1010
server::{ServerHandle, WeakServerHandle},
1111
};
1212

1313
use super::{CurrentServer, UserHandle, Users, WeakUserHandle};
1414

1515
impl Users {
16-
pub fn transfer_all_users(&self, _server: &ServerHandle) -> u32 {
17-
// TODO: Move all players from server to another server
18-
0
16+
pub fn transfer_all_users(&self, server: &ServerHandle) -> u32 {
17+
let controller = self
18+
.controller
19+
.upgrade()
20+
.expect("Failed to upgrade controller. This should never happen");
21+
let users = self.get_users_on_server(server);
22+
let mut count = 0;
23+
24+
for user in &users {
25+
if let Some(fallback_server) = controller.get_servers().find_fallback_server(server) {
26+
if let Some(transfer) =
27+
self.resolve_transfer(user, &TransferTarget::Server(fallback_server))
28+
{
29+
if self.transfer_user(transfer) {
30+
count += 1;
31+
}
32+
}
33+
}
34+
}
35+
36+
count
1937
}
2038

2139
pub fn resolve_transfer(&self, user: &UserHandle, target: &TransferTarget) -> Option<Transfer> {
@@ -25,25 +43,18 @@ impl Users {
2543
return Some(Transfer::new(
2644
Arc::downgrade(user),
2745
from.clone(),
28-
to.clone(),
46+
Arc::downgrade(to),
2947
));
3048
}
3149
TransferTarget::Group(group) => {
32-
if let Some(group) = group.upgrade() {
33-
if let Some(to) = group.get_free_server() {
34-
return Some(Transfer::new(
35-
Arc::downgrade(user),
36-
from.clone(),
37-
Arc::downgrade(&to),
38-
));
39-
} else {
40-
warn!("Failed to find free server in group {} while resolving transfer of user {}", group.name, user.name);
41-
}
50+
if let Some(to) = group.get_free_server() {
51+
return Some(Transfer::new(
52+
Arc::downgrade(user),
53+
from.clone(),
54+
Arc::downgrade(&to),
55+
));
4256
} else {
43-
error!(
44-
"Failed to upgrade group handle while resolving transfer of user {}",
45-
user.name
46-
);
57+
warn!("Failed to find free server in group {} while resolving transfer of user {}", group.name, user.name);
4758
}
4859
}
4960
}
@@ -62,7 +73,7 @@ impl Users {
6273
let controller = self
6374
.controller
6475
.upgrade()
65-
.expect("Failed to upgrade controller");
76+
.expect("Failed to upgrade controller. This should never happen");
6677
controller.get_event_bus().dispatch(
6778
&EventKey::Transfer(from.uuid),
6879
&UserTransferRequested {
@@ -81,8 +92,8 @@ impl Users {
8192
}
8293

8394
pub enum TransferTarget {
84-
Server(WeakServerHandle),
85-
Group(WeakGroupHandle),
95+
Server(ServerHandle),
96+
Group(GroupHandle),
8697
}
8798

8899
#[derive(Clone, Debug)]

controller/src/network/admin.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use tonic::{async_trait, Request, Response, Status};
44
use crate::controller::{
55
group::ScalingPolicy,
66
node::{Capabilities, RemoteController},
7-
server::{Deployment, KeyValue, Resources, Retention},
7+
server::{Deployment, FallbackPolicy, KeyValue, Resources, Retention},
88
ControllerHandle, CreationResult,
99
};
1010

@@ -146,6 +146,12 @@ impl AdminService for AdminServiceImpl {
146146
_ => Retention::Temporary,
147147
};
148148
}
149+
if let Some(value) = value.fallback {
150+
deployment.fallback = FallbackPolicy {
151+
enabled: value.enabled,
152+
priority: value.priority,
153+
};
154+
}
149155
}
150156

151157
/* Nodes */

protocol/grpc/admin/admin.proto

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ message Group {
6969
repeated KeyValue settings = 2;
7070
repeated KeyValue environment = 3;
7171
optional Retention diskRetention = 4;
72+
optional Fallback fallback = 5;
73+
74+
message Fallback {
75+
bool enabled = 1;
76+
int32 priority = 2;
77+
}
7278

7379
message KeyValue {
7480
string key = 1;

0 commit comments

Comments
 (0)