Skip to content

Commit

Permalink
fix(containers)!: race conditions between multiple app instances
Browse files Browse the repository at this point in the history
When running tests in Wing, an isolated environment is created for every test. This means we must create a the container workload using a unique name, or otherwise the containers will mix up with each other.

BREAKING CHANGE: the `getPublicUrl()` and `getInternalUrl()` APIs were replaced with properties (`publicUrl` and `internalUrl`).
  • Loading branch information
eladb committed Nov 27, 2023
1 parent dfe3b82 commit f16a323
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 51 deletions.
9 changes: 2 additions & 7 deletions containers/api.w
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
pub interface IWorkload extends std.IResource {
/** internal url, `nil` if there is no exposed port */
getInternalUrl(): str?;

/** extern url, `nil` if there is no exposed port or if `public` is `false` */
getPublicUrl(): str?;
}

pub struct ContainerOpts {
name: str;
image: str;

/** Internal container port to expose */
port: num?;
env: Map<str?>?;
readiness: str?; // http get
Expand Down
29 changes: 12 additions & 17 deletions containers/workload.sim.w
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ bring sim;
bring "./api.w" as api;
bring "./utils.w" as utils;

pub class Workload_sim impl api.IWorkload {
pub class Workload_sim {
containerId: str;
publicUrlKey: str?;
internalUrlKey: str?;

pub publicUrl: str?;
pub internalUrl: str?;

props: api.WorkloadProps;
appDir: str;
imageTag: str;
Expand All @@ -24,10 +27,10 @@ pub class Workload_sim impl api.IWorkload {
let hash = utils.resolveContentHash(this, props);
if hash? {
this.imageTag = "{props.name}:{hash}";
this.containerId = "{props.name}-{hash}";
this.containerId = "{props.name}-{hash}-{util.nanoid()}";
} else {
this.imageTag = props.image;
this.containerId = props.name;
this.containerId = "{props.name}-{util.nanoid()}";
}

this.public = props.public ?? false;
Expand All @@ -37,11 +40,15 @@ pub class Workload_sim impl api.IWorkload {
throw "'port' is required if 'public' is enabled";
}

this.publicUrlKey = "public_url";
let key = "public_url";
this.publicUrl = this.state.token(key);
this.publicUrlKey = key;
}

if props.port? {
this.internalUrlKey = "internal_url";
let key = "internal_url";
this.internalUrl = this.state.token(key);
this.internalUrlKey = key;
}

let s = new cloud.Service(inflight () => {
Expand All @@ -53,18 +60,6 @@ pub class Workload_sim impl api.IWorkload {
std.Node.of(this.state).hidden = true;
}

pub getInternalUrl(): str? {
if let k = this.internalUrlKey {
return this.state.token(k);
}
}

pub getPublicUrl(): str? {
if let k = this.publicUrlKey {
return this.state.token(k);
}
}

inflight start(): void {
log("starting workload...");

Expand Down
14 changes: 3 additions & 11 deletions containers/workload.tfaws.w
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ bring "./utils.w" as utils;
bring "@cdktf/provider-kubernetes" as k8s;
bring "@cdktf/provider-helm" as helm;

pub class Workload_tfaws impl api.IWorkload {
internalUrl: str?;
publicUrl: str?;
pub class Workload_tfaws {
pub internalUrl: str?;
pub publicUrl: str?;

new(props: api.WorkloadProps) {
let cluster = eks.Cluster.getOrCreate(this);
Expand Down Expand Up @@ -147,13 +147,5 @@ pub class Workload_tfaws impl api.IWorkload {
this.publicUrl = "http://{hostname}";
}
}

pub getPublicUrl(): str? {
return this.publicUrl;
}

pub getInternalUrl(): str? {
return this.internalUrl;
}
}

29 changes: 13 additions & 16 deletions containers/workload.w
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,29 @@ bring "./workload.tfaws.w" as tfaws;
bring "./api.w" as api;
bring "./utils.w" as utils;

pub class Workload impl api.IWorkload {
inner: api.IWorkload;
bring http;

pub class Workload {
/** internal url, `nil` if there is no exposed port */
pub internalUrl: str?;

/** extern url, `nil` if there is no exposed port or if `public` is `false` */
pub publicUrl: str?;

new(props: api.WorkloadProps) {
let target = util.env("WING_TARGET");

if target == "sim" {
this.inner = new sim.Workload_sim(props) as props.name;
let w = new sim.Workload_sim(props) as props.name;
this.internalUrl = w.internalUrl;
this.publicUrl = w.publicUrl;

} elif target == "tf-aws" {
this.inner = new tfaws.Workload_tfaws(props) as props.name;
let w = new tfaws.Workload_tfaws(props) as props.name;
this.internalUrl = w.internalUrl;
this.publicUrl = w.publicUrl;
} else {
throw "unsupported target {target}";
}


this.internalUrl = this.inner.getInternalUrl();
this.publicUrl = this.inner.getPublicUrl();
}

pub getInternalUrl(): str? {
return this.inner.getInternalUrl();
}

pub getPublicUrl(): str? {
return this.inner.getPublicUrl();
}
}

0 comments on commit f16a323

Please sign in to comment.