Skip to content

Commit b5e4765

Browse files
authored
Merge pull request #1070 from rust-lang/unification
Unify the one-off and websocket Coordinator factories
2 parents 0fdc8eb + 18b37db commit b5e4765

File tree

7 files changed

+107
-159
lines changed

7 files changed

+107
-159
lines changed

compiler/base/Dockerfile

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ COPY --chown=playground entrypoint.sh /playground/tools/
5656

5757
FROM toolchain as wasm-tools
5858

59-
RUN cargo install wasm-tools
59+
RUN cargo install --locked wasm-tools
6060

6161
# Fetch all the crate source files
6262

@@ -68,18 +68,11 @@ COPY --chown=playground Cargo.toml /playground/Cargo.toml
6868
COPY --chown=playground crate-information.json /playground/crate-information.json
6969
RUN cargo fetch
7070

71-
# Build our tool for modifying Cargo.toml at runtime
72-
73-
FROM toolchain as modify-cargo-toml
74-
75-
COPY --chown=playground modify-cargo-toml /playground/modify-cargo-toml
76-
RUN cargo build --release --manifest-path=/playground/modify-cargo-toml/Cargo.toml
77-
7871
# Set up cargo-chef for faster builds
7972

8073
FROM toolchain as chef-available
8174

82-
RUN cargo install cargo-chef
75+
RUN cargo install --locked cargo-chef
8376

8477
WORKDIR /orchestrator
8578

@@ -99,10 +92,10 @@ FROM chef-available as build-orchestrator
9992
COPY --chown=playground asm-cleanup /asm-cleanup
10093
COPY --chown=playground modify-cargo-toml /modify-cargo-toml
10194
COPY --chown=playground --from=prepare-orchestrator /orchestrator/recipe.json /orchestrator/recipe.json
102-
RUN cargo chef cook --release
95+
RUN cargo chef cook --locked --release
10396

10497
COPY --chown=playground orchestrator /orchestrator
105-
RUN cargo install --path .
98+
RUN cargo install --locked --path .
10699

107100
# Compiler and pre-compiled crates
108101

@@ -116,7 +109,6 @@ RUN cargo clippy
116109
RUN if [ "${channel}" = 'nightly' ]; then cargo miri setup; cargo miri run; fi
117110
RUN rm src/*.rs
118111

119-
COPY --from=modify-cargo-toml /playground/modify-cargo-toml/target/release/modify-cargo-toml /playground/.cargo/bin
120112
COPY --from=build-orchestrator /playground/.cargo/bin/worker /playground/.cargo/bin/worker
121113
COPY --from=wasm-tools /playground/.cargo/bin/wasm-tools /playground/.cargo/bin
122114
COPY --chown=playground cargo-wasm /playground/.cargo/bin

compiler/base/entrypoint.sh

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,6 @@
22

33
set -eu
44

5-
if [[ -z "${PLAYGROUND_ORCHESTRATOR:-}" ]]; then
6-
timeout=${PLAYGROUND_TIMEOUT:-10}
7-
8-
modify-cargo-toml
9-
10-
# Don't use `exec` here. The shell is what prints out the useful
11-
# "Killed" message
12-
timeout --signal=KILL ${timeout} "$@"
13-
else
14-
exec "$@"
15-
fi
5+
# This entrypoint is a no-op but I'm leaving it to be easier to
6+
# re-create at some future point.
7+
exec "$@"

compiler/base/modify-cargo-toml/src/main.rs

Lines changed: 0 additions & 46 deletions
This file was deleted.

compiler/base/orchestrator/src/coordinator.rs

Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -820,25 +820,33 @@ enum DemultiplexCommand {
820820
ListenOnce(JobId, oneshot::Sender<WorkerMessage>),
821821
}
822822

823-
#[derive(Debug, Copy, Clone)]
824-
pub struct CoordinatorId {
825-
start: u64,
826-
id: u64,
823+
/// The [`Coordinator`][] usually represents a mostly-global resource,
824+
/// such as a Docker container. To avoid conflicts, each container
825+
/// must have a unique name, but that uniqueness can only be
826+
/// guaranteed by whoever is creating [`Coordinator`][]s via the
827+
/// [`CoordinatorFactory`][].
828+
pub trait IdProvider: Send + Sync + fmt::Debug + 'static {
829+
fn next(&self) -> String;
827830
}
828831

829-
/// Enforces a limited number of concurrent `Coordinator`s.
832+
/// A reasonable choice when there's a single [`IdProvider`][] in the
833+
/// entire process.
834+
///
835+
/// This represents uniqueness via a combination of
836+
///
837+
/// 1. **process start time** — this helps avoid conflicts from other
838+
/// processes, assuming they were started at least one second apart.
839+
///
840+
/// 2. **instance counter** — this avoids conflicts from other
841+
/// [`Coordinator`][]s started inside this process.
830842
#[derive(Debug)]
831-
pub struct CoordinatorFactory {
832-
semaphore: Arc<Semaphore>,
833-
843+
pub struct GlobalIdProvider {
834844
start: u64,
835845
id: AtomicU64,
836846
}
837847

838-
impl CoordinatorFactory {
839-
pub fn new(maximum: usize) -> Self {
840-
let semaphore = Arc::new(Semaphore::new(maximum));
841-
848+
impl GlobalIdProvider {
849+
pub fn new() -> Self {
842850
let now = std::time::SystemTime::now();
843851
let start = now
844852
.duration_since(std::time::UNIX_EPOCH)
@@ -847,28 +855,40 @@ impl CoordinatorFactory {
847855

848856
let id = AtomicU64::new(0);
849857

850-
Self {
851-
semaphore,
852-
start,
853-
id,
854-
}
858+
Self { start, id }
855859
}
860+
}
856861

857-
fn next_id(&self) -> CoordinatorId {
862+
impl IdProvider for GlobalIdProvider {
863+
fn next(&self) -> String {
858864
let start = self.start;
859865
let id = self.id.fetch_add(1, Ordering::SeqCst);
860866

861-
CoordinatorId { start, id }
867+
format!("{start}-{id}")
868+
}
869+
}
870+
871+
/// Enforces a limited number of concurrent `Coordinator`s.
872+
#[derive(Debug)]
873+
pub struct CoordinatorFactory {
874+
semaphore: Arc<Semaphore>,
875+
ids: Arc<dyn IdProvider>,
876+
}
877+
878+
impl CoordinatorFactory {
879+
pub fn new(ids: Arc<dyn IdProvider>, maximum: usize) -> Self {
880+
let semaphore = Arc::new(Semaphore::new(maximum));
881+
882+
Self { semaphore, ids }
862883
}
863884

864885
pub fn build<B>(&self) -> Coordinator<B>
865886
where
866-
B: Backend + From<CoordinatorId>,
887+
B: Backend + From<Arc<dyn IdProvider>>,
867888
{
868889
let semaphore = self.semaphore.clone();
869890

870-
let id = self.next_id();
871-
let backend = B::from(id);
891+
let backend = B::from(self.ids.clone());
872892

873893
Coordinator::new(semaphore, backend)
874894
}
@@ -2586,25 +2606,20 @@ fn basic_secure_docker_command() -> Command {
25862606
}
25872607

25882608
pub struct DockerBackend {
2589-
id: CoordinatorId,
2590-
instance: AtomicU64,
2609+
ids: Arc<dyn IdProvider>,
25912610
}
25922611

2593-
impl From<CoordinatorId> for DockerBackend {
2594-
fn from(id: CoordinatorId) -> Self {
2595-
Self {
2596-
id,
2597-
instance: Default::default(),
2598-
}
2612+
impl From<Arc<dyn IdProvider>> for DockerBackend {
2613+
fn from(ids: Arc<dyn IdProvider>) -> Self {
2614+
Self { ids }
25992615
}
26002616
}
26012617

26022618
impl DockerBackend {
26032619
fn next_name(&self) -> String {
2604-
let CoordinatorId { start, id } = self.id;
2605-
let instance = self.instance.fetch_add(1, Ordering::SeqCst);
2620+
let id = self.ids.next();
26062621

2607-
format!("playground-{start}-{id}-{instance}")
2622+
format!("playground-{id}")
26082623
}
26092624
}
26102625

@@ -2617,6 +2632,9 @@ impl Backend for DockerBackend {
26172632
.args(["--name", &name])
26182633
.arg("-i")
26192634
.args(["-a", "stdin", "-a", "stdout", "-a", "stderr"])
2635+
// PLAYGROUND_ORCHESTRATOR is vestigial; I'm leaving it
2636+
// for a bit to allow new containers to get built and
2637+
// distributed.
26202638
.args(["-e", "PLAYGROUND_ORCHESTRATOR=1"])
26212639
.arg("--rm")
26222640
.arg(channel.to_container_name())
@@ -2791,8 +2809,8 @@ mod tests {
27912809
project_dir: TempDir,
27922810
}
27932811

2794-
impl From<CoordinatorId> for TestBackend {
2795-
fn from(_id: CoordinatorId) -> Self {
2812+
impl From<Arc<dyn IdProvider>> for TestBackend {
2813+
fn from(_ids: Arc<dyn IdProvider>) -> Self {
27962814
static COMPILE_WORKER_ONCE: Once = Once::new();
27972815

27982816
COMPILE_WORKER_ONCE.call_once(|| {
@@ -2846,8 +2864,12 @@ mod tests {
28462864
.unwrap_or(5)
28472865
});
28482866

2849-
static TEST_COORDINATOR_FACTORY: Lazy<CoordinatorFactory> =
2850-
Lazy::new(|| CoordinatorFactory::new(*MAX_CONCURRENT_TESTS));
2867+
static TEST_COORDINATOR_ID_PROVIDER: Lazy<Arc<GlobalIdProvider>> =
2868+
Lazy::new(|| Arc::new(GlobalIdProvider::new()));
2869+
2870+
static TEST_COORDINATOR_FACTORY: Lazy<CoordinatorFactory> = Lazy::new(|| {
2871+
CoordinatorFactory::new(TEST_COORDINATOR_ID_PROVIDER.clone(), *MAX_CONCURRENT_TESTS)
2872+
});
28512873

28522874
fn new_coordinator_test() -> Coordinator<TestBackend> {
28532875
TEST_COORDINATOR_FACTORY.build()

tests/Gemfile.lock

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
GEM
22
remote: https://rubygems.org/
33
specs:
4-
addressable (2.8.6)
5-
public_suffix (>= 2.0.2, < 6.0)
4+
addressable (2.8.7)
5+
public_suffix (>= 2.0.2, < 7.0)
66
base64 (0.2.0)
77
capybara (3.40.0)
88
addressable
@@ -21,36 +21,38 @@ GEM
2121
launchy (3.0.1)
2222
addressable (~> 2.8)
2323
childprocess (~> 5.0)
24+
logger (1.6.0)
2425
matrix (0.4.2)
2526
mini_mime (1.1.5)
2627
mini_portile2 (2.8.7)
27-
nokogiri (1.16.5)
28+
nokogiri (1.16.6)
2829
mini_portile2 (~> 2.8.2)
2930
racc (~> 1.4)
30-
public_suffix (5.0.5)
31+
public_suffix (6.0.0)
3132
racc (1.8.0)
32-
rack (3.0.11)
33+
rack (3.1.4)
3334
rack-test (2.1.0)
3435
rack (>= 1.3)
3536
regexp_parser (2.9.2)
36-
rexml (3.2.8)
37-
strscan (>= 3.0.9)
37+
rexml (3.3.1)
38+
strscan
3839
rspec (3.13.0)
3940
rspec-core (~> 3.13.0)
4041
rspec-expectations (~> 3.13.0)
4142
rspec-mocks (~> 3.13.0)
4243
rspec-core (3.13.0)
4344
rspec-support (~> 3.13.0)
44-
rspec-expectations (3.13.0)
45+
rspec-expectations (3.13.1)
4546
diff-lcs (>= 1.2.0, < 2.0)
4647
rspec-support (~> 3.13.0)
4748
rspec-mocks (3.13.1)
4849
diff-lcs (>= 1.2.0, < 2.0)
4950
rspec-support (~> 3.13.0)
5051
rspec-support (3.13.1)
5152
rubyzip (2.3.2)
52-
selenium-webdriver (4.21.1)
53+
selenium-webdriver (4.22.0)
5354
base64 (~> 0.2)
55+
logger (~> 1.4)
5456
rexml (~> 3.2, >= 3.2.5)
5557
rubyzip (>= 1.2.2, < 3.0)
5658
websocket (~> 1.0)

0 commit comments

Comments
 (0)