Skip to content

Commit 2b6faaa

Browse files
committed
chore(core): update default region name to default
1 parent f5e24c8 commit 2b6faaa

File tree

19 files changed

+342
-40
lines changed

19 files changed

+342
-40
lines changed

out/errors/actor.no_runners_available.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

out/errors/guard.invalid_regional_host.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

out/errors/guard.must_use_regional_host.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

out/openapi.json

Lines changed: 7 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/common/config/src/config/topology.rs

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,20 @@ impl Default for Topology {
4848
Topology {
4949
datacenter_label: 1,
5050
datacenters: vec![Datacenter {
51-
name: "local".into(),
51+
name: "default".into(),
5252
datacenter_label: 1,
5353
is_leader: true,
54-
api_peer_url: Url::parse(&format!(
54+
public_url: Url::parse(&format!(
5555
"http://127.0.0.1:{}",
56-
crate::defaults::ports::API_PEER
56+
crate::defaults::ports::GUARD
5757
))
5858
.unwrap(),
59-
guard_url: Url::parse(&format!(
59+
api_peer_url: Url::parse(&format!(
6060
"http://127.0.0.1:{}",
61-
crate::defaults::ports::GUARD
61+
crate::defaults::ports::API_PEER
6262
))
6363
.unwrap(),
64+
valid_hosts: None,
6465
}],
6566
}
6667
}
@@ -72,8 +73,28 @@ pub struct Datacenter {
7273
pub name: String,
7374
pub datacenter_label: u16,
7475
pub is_leader: bool,
75-
/// Url of the api-peer service
76+
/// Public origin that can be used to connect to this region.
77+
pub public_url: Url,
78+
/// URL of the api-peer service
7679
pub api_peer_url: Url,
77-
/// Url of the peer's guard server
78-
pub guard_url: Url,
80+
/// List of hosts that are valid to connect to this region with. This is used in regional
81+
/// endpoints to validate that incoming requests to this datacenter are going to a
82+
/// region-specific domain.
83+
///
84+
/// IMPORTANT: Do not use a global origin that routes to multiple different regions. This will
85+
/// cause unpredictable behavior when requests are expected to go to a specific region.
86+
#[serde(default)]
87+
pub valid_hosts: Option<Vec<String>>,
88+
}
89+
90+
impl Datacenter {
91+
pub fn is_valid_regional_host(&self, host: &str) -> bool {
92+
if let Some(valid_hosts) = &self.valid_hosts {
93+
// Check if host is in the valid_hosts list
94+
valid_hosts.iter().any(|valid_host| valid_host == host)
95+
} else {
96+
// Check if host matches the origin of public_url
97+
self.public_url.host_str() == Some(host)
98+
}
99+
}
79100
}

packages/common/test-deps/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ impl TestDeps {
4848
name: format!("dc-{dc_id}"),
4949
datacenter_label: dc_id,
5050
is_leader: dc_id == dc_ids[0], // First DC in list is leader
51+
public_url: Url::parse(&format!("http://127.0.0.1:{guard_port}"))?,
5152
api_peer_url: Url::parse(&format!("http://127.0.0.1:{api_peer_port}"))?,
52-
guard_url: Url::parse(&format!("http://127.0.0.1:{guard_port}"))?,
53+
valid_hosts: None,
5354
});
5455
ports.push((api_peer_port, guard_port));
5556
}

packages/common/types/src/datacenters.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use utoipa::ToSchema;
44
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
55
#[serde(deny_unknown_fields)]
66
pub struct Datacenter {
7-
pub datacenter_label: u16,
7+
pub label: u16,
88
pub name: String,
9+
pub url: String,
910
}

packages/core/api-public/src/actors/create.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,21 @@ async fn create_inner(
6868
) -> Result<CreateResponse> {
6969
ctx.skip_auth();
7070

71-
// Determine which datacenter to create the actor in
72-
let target_dc_label = if let Some(dc_name) = &query.datacenter {
73-
ctx.config()
74-
.dc_for_name(dc_name)
75-
.ok_or_else(|| crate::errors::Datacenter::NotFound.build())?
76-
.datacenter_label
77-
} else {
78-
ctx.config().dc_label()
79-
};
71+
let namespace = ctx
72+
.op(namespace::ops::resolve_for_name_global::Input {
73+
name: query.namespace.clone(),
74+
})
75+
.await?
76+
.ok_or_else(|| namespace::errors::Namespace::NotFound.build())?;
77+
78+
let target_dc_label = super::utils::find_dc_for_actor_creation(
79+
&ctx,
80+
namespace.namespace_id,
81+
&query.namespace,
82+
&body.runner_name_selector,
83+
query.datacenter.as_ref().map(String::as_str),
84+
)
85+
.await?;
8086

8187
let query = rivet_api_types::actors::create::CreateQuery {
8288
namespace: query.namespace,

packages/core/api-public/src/actors/get_or_create.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use utoipa::{IntoParams, ToSchema};
1414

1515
use crate::actors::utils;
1616
use crate::ctx::ApiCtx;
17-
use crate::errors;
1817

1918
#[derive(Debug, Deserialize, IntoParams)]
2019
#[serde(deny_unknown_fields)]
@@ -123,15 +122,14 @@ async fn get_or_create_inner(
123122
}
124123

125124
// Actor doesn't exist for any key, create it
126-
// Determine which datacenter to create the actor in
127-
let target_dc_label = if let Some(dc_name) = &query.datacenter {
128-
ctx.config()
129-
.dc_for_name(dc_name)
130-
.ok_or_else(|| errors::Datacenter::NotFound.build())?
131-
.datacenter_label
132-
} else {
133-
ctx.config().dc_label()
134-
};
125+
let target_dc_label = super::utils::find_dc_for_actor_creation(
126+
&ctx,
127+
namespace.namespace_id,
128+
&query.namespace,
129+
&body.runner_name_selector,
130+
query.datacenter.as_ref().map(String::as_str),
131+
)
132+
.await?;
135133

136134
let actor_id = Id::new_v1(target_dc_label);
137135

packages/core/api-public/src/actors/utils.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,3 +184,39 @@ pub fn extract_duplicate_key_error(err: &anyhow::Error) -> Option<Id> {
184184

185185
None
186186
}
187+
188+
/// Determine the datacenter label to create the actor in.
189+
pub async fn find_dc_for_actor_creation(
190+
ctx: &ApiCtx,
191+
namespace_id: Id,
192+
namespace_name: &str,
193+
runner_name: &str,
194+
dc_name: Option<&str>,
195+
) -> Result<u16> {
196+
let target_dc_label = if let Some(dc_name) = &dc_name {
197+
// Use user-configured DC
198+
ctx.config()
199+
.dc_for_name(dc_name)
200+
.ok_or_else(|| crate::errors::Datacenter::NotFound.build())?
201+
.datacenter_label
202+
} else {
203+
// Find the nearest DC with runners
204+
let res = ctx
205+
.op(pegboard::ops::runner::find_dc_with_runner::Input {
206+
namespace_id,
207+
runner_name: runner_name.into(),
208+
})
209+
.await?;
210+
if let Some(dc_label) = res.dc_label {
211+
dc_label
212+
} else {
213+
return Err(pegboard::errors::Actor::NoRunnersAvailable {
214+
namespace: namespace_name.into(),
215+
runner_name: runner_name.into(),
216+
}
217+
.build());
218+
}
219+
};
220+
221+
Ok(target_dc_label)
222+
}

0 commit comments

Comments
 (0)