Skip to content

Commit 622d699

Browse files
authored
feat: adding chrony for time synchronization and consistent latencies (#19)
* fix: fixing deployment timing * feat: adding asymmetrical network and fetching of ntp data * feat: setting network latency * chore: deleting bs file * feat: adding chrony for time synchronization and consistent latencies
1 parent 519205d commit 622d699

2 files changed

Lines changed: 72 additions & 46 deletions

File tree

.idea/misc.xml

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

diningPhilosophers/deploy.py

Lines changed: 70 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,18 @@
3030
roles, networks = provider.init()
3131
roles = en.sync_info(roles, networks)
3232

33+
print(">>> Installing and configuring Chrony on all nodes...")
34+
with en.actions(roles=roles) as a:
35+
a.apt(name=["chrony"], state="present", update_cache=True)
36+
a.service(name="chrony", state="started", enabled=True)
37+
a.shell("chronyc makestep")
38+
3339
# Initial Docker engine deployment
3440
registry_opts = dict(type="external", ip="docker-cache.grid5000.fr", port=80)
3541
d = en.Docker(
3642
agent=roles["arbitrator"] + roles["worker"],
3743
bind_var_docker="/tmp/docker",
38-
registry_opts=registry_opts
44+
registry_opts=registry_opts,
3945
)
4046
d.deploy()
4147

@@ -62,8 +68,8 @@
6268
# Network emulation
6369
netem = en.NetemHTB()
6470
netem.add_constraints(
65-
src=roles["worker"],
66-
dest=roles["arbitrator"],
71+
src=roles["worker"] + roles["arbitrator"],
72+
dest=roles["worker"] + roles["arbitrator"],
6773
delay="10ms",
6874
rate="1gbit",
6975
symmetric=True,
@@ -79,37 +85,46 @@
7985
a.file(path="/tmp/metrics", state="absent")
8086
a.file(path="/tmp/metrics", state="directory", mode="0777")
8187
a.file(path=COMPONENTS_PATH, state="directory")
82-
a.copy(src="config/redis/components-grid5000/",
83-
dest=COMPONENTS_PATH + "/")
88+
a.copy(src="config/redis/components-grid5000/", dest=COMPONENTS_PATH + "/")
8489

85-
# Deploy Containers on Arbitrator
90+
# Deploy containers
8691
with en.actions(roles=roles["arbitrator"]) as a:
8792
a.docker_container(
88-
name="redis", image=REDIS_IMAGE,
89-
network_mode="host", state="started"
93+
name="redis", image=REDIS_IMAGE, network_mode="host", state="started"
9094
)
9195
a.docker_container(
92-
name="placement", image=PLACEMENT_IMAGE,
93-
network_mode="host", state="started",
94-
command=["./placement", "--port", "50006"]
96+
name="placement",
97+
image=PLACEMENT_IMAGE,
98+
network_mode="host",
99+
state="started",
100+
command=["./placement", "--port", "50006"],
95101
)
96102
a.docker_container(
97-
name="arbitrator-sidecar", image=SIDECAR_IMAGE,
98-
network_mode="host", state="started",
103+
name="arbitrator-sidecar",
104+
image=SIDECAR_IMAGE,
105+
network_mode="host",
106+
state="started",
99107
command=[
100108
"./daprd",
101-
"--app-id", "arbitrator-sidecar",
102-
"--app-port", "3000",
103-
"--resources-path", "/components",
104-
"--placement-host-address", "localhost:50006",
105-
"--metrics-port", "9091",
109+
"--app-id",
110+
"arbitrator-sidecar",
111+
"--app-port",
112+
"3000",
113+
"--resources-path",
114+
"/components",
115+
"--placement-host-address",
116+
"localhost:50006",
117+
"--metrics-port",
118+
"9091",
106119
],
107120
volumes=[f"{COMPONENTS_PATH}:/components"],
108121
)
109122
time.sleep(10)
110123
a.docker_container(
111-
name="arbitrator", image=ACTOR_IMAGE,
112-
network_mode="host", state="started",
124+
name="arbitrator",
125+
image=ACTOR_IMAGE,
126+
network_mode="host",
127+
state="started",
113128
volumes=["/tmp/metrics:/metrics:rw"],
114129
env={
115130
"ROLE": "arbitrator",
@@ -120,35 +135,44 @@
120135
},
121136
)
122137

123-
# Deploy Containers on Workers
124138
for i, host in enumerate(roles["worker"]):
125139
with en.actions(pattern_hosts=host.address, roles=roles) as a:
126140
a.docker_container(
127-
name="redis", image=REDIS_IMAGE,
128-
network_mode="host", state="started"
141+
name="redis", image=REDIS_IMAGE, network_mode="host", state="started"
129142
)
130143
a.docker_container(
131-
name="placement", image=PLACEMENT_IMAGE,
132-
network_mode="host", state="started",
133-
command=["./placement", "--port", "50006"]
144+
name="placement",
145+
image=PLACEMENT_IMAGE,
146+
network_mode="host",
147+
state="started",
148+
command=["./placement", "--port", "50006"],
134149
)
135150
a.docker_container(
136-
name=f"w{i}-sidecar", image=SIDECAR_IMAGE,
137-
network_mode="host", state="started",
151+
name=f"w{i}-sidecar",
152+
image=SIDECAR_IMAGE,
153+
network_mode="host",
154+
state="started",
138155
command=[
139156
"./daprd",
140-
"--app-id", f"w{i}-sidecar",
141-
"--app-port", "3000",
142-
"--resources-path", "/components",
143-
"--placement-host-address", "localhost:50006",
144-
"--metrics-port", "9091",
157+
"--app-id",
158+
f"w{i}-sidecar",
159+
"--app-port",
160+
"3000",
161+
"--resources-path",
162+
"/components",
163+
"--placement-host-address",
164+
"localhost:50006",
165+
"--metrics-port",
166+
"9091",
145167
],
146168
volumes=[f"{COMPONENTS_PATH}:/components"],
147169
)
148170
time.sleep(10)
149171
a.docker_container(
150-
name=f"w{i}", image=ACTOR_IMAGE,
151-
network_mode="host", state="started",
172+
name=f"w{i}",
173+
image=ACTOR_IMAGE,
174+
network_mode="host",
175+
state="started",
152176
volumes=["/tmp/metrics:/metrics:rw"],
153177
env={
154178
"PHILOSOPHER_ID": str(i),
@@ -160,24 +184,28 @@
160184

161185
# Wait for data collection
162186
print(f"--- {run_label}: Collecting data for {TIME_BEFORE_FETCH}s ---")
163-
for _ in tqdm(range(TIME_BEFORE_FETCH), desc=run_label, unit="s",
164-
mininterval=60):
187+
for _ in tqdm(range(TIME_BEFORE_FETCH), desc=run_label, unit="s", mininterval=60):
165188
time.sleep(1)
166189

167-
# Capture NTP timing data on all nodes
190+
# Capture Chrony tracking data
168191
with en.actions(roles=roles) as a:
169-
a.shell("ntpq -p > /tmp/metrics/ntp_stats.txt")
192+
a.shell("chronyc tracking > /tmp/metrics/chrony_tracking.txt")
193+
a.shell("chronyc sources -v > /tmp/metrics/chrony_sources.txt")
170194

171-
# Fetch and Organize Results locally
195+
# Fetch and organize results
172196
run_dest = LOCAL_ROOT / run_label
173197
run_dest.mkdir(parents=True, exist_ok=True)
174198

175199
with en.actions(roles=roles) as a:
176200
a.archive(path="/tmp/metrics", dest="/tmp/metrics.tar.gz", format="gz")
177201
a.fetch(src="/tmp/metrics.tar.gz", dest=str(run_dest), flat=False)
178202

179-
# Local extraction
180-
print(f"--- {run_label}: Extracting results ---")
203+
print(f"--- {run_label}: Cleaning up and extracting ---")
204+
205+
with en.actions(roles=roles) as a:
206+
a.shell("docker rm -f $(docker ps -aq) || true")
207+
208+
# Local file flattening
181209
for host in en.get_hosts(roles):
182210
host_dir = run_dest / host.address
183211
tar_path = host_dir / "tmp" / "metrics.tar.gz"
@@ -192,9 +220,5 @@
192220
except OSError:
193221
pass
194222

195-
# Clean up all containers for next run
196-
with en.actions(roles=roles) as a:
197-
a.shell("docker rm -f $(docker ps -aq) || true")
198-
199223
print(f"\n--- SUCCESS: All {NUM_RUNS} runs finished. Data in {LOCAL_ROOT} ---")
200224
provider.destroy()

0 commit comments

Comments
 (0)