Skip to content

Commit a449a77

Browse files
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
1 parent d73d438 commit a449a77

File tree

1 file changed

+64
-21
lines changed

1 file changed

+64
-21
lines changed

simulate.py

Lines changed: 64 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
from __future__ import annotations
2-
import random
2+
33
import argparse
44
import asyncio
5-
from enum import Enum
65
import json
76
import os
7+
import random
88
import secrets
9+
import time
910
from dataclasses import dataclass
1011
from datetime import datetime
1112
from functools import partial
12-
import time
1313
from typing import Any, Coroutine, List
1414

1515
import aiohttp
1616
import aiometer
1717
from playwright.async_api import Browser, async_playwright
1818
from yarl import URL
1919

20+
2021
@dataclass
2122
class TimedResult[T]:
2223
duration: float
2324
result: T
2425

26+
2527
@dataclass
2628
class HubAccess:
2729
"""
@@ -63,6 +65,7 @@ class FailedServer(Server):
6365
start_failure_time: datetime
6466
startup_events: List[dict]
6567

68+
6669
@dataclass
6770
class NBGitpullerURL:
6871
repo: str
@@ -74,7 +77,7 @@ def make_fullpath(self, server_url: URL, targetpath: str) -> URL:
7477
"repo": self.repo,
7578
"branch": self.ref,
7679
"targetPath": targetpath,
77-
"urlPath": os.path.join("tree", targetpath, self.open_path)
80+
"urlPath": os.path.join("tree", targetpath, self.open_path),
7881
}
7982

8083
return (server_url / "git-pull").with_query(query_params)
@@ -101,14 +104,19 @@ async def load_nbgitpuller_url(
101104
targetpath = secrets.token_hex(8)
102105
going_to = nbgitpuller_url.make_fullpath(server.server_url, targetpath)
103106
await page.goto(str(going_to))
104-
expected_final_full_url = str(nbgitpuller_url.make_expectedpath(server.server_url, targetpath))
107+
expected_final_full_url = str(
108+
nbgitpuller_url.make_expectedpath(server.server_url, targetpath)
109+
)
105110
await page.wait_for_url(expected_final_full_url, timeout=120 * 10 * 1000)
106111
await page.wait_for_load_state("networkidle")
107112
await page.screenshot(path=screenshot_name)
108113
return TimedResult(time.perf_counter() - start_time, None)
109114

115+
110116
async def start_named_server(
111-
session: aiohttp.ClientSession, server: Server, profile_options: dict[str, str] | None = None,
117+
session: aiohttp.ClientSession,
118+
server: Server,
119+
profile_options: dict[str, str] | None = None,
112120
) -> TimedResult[RunningServer | None]:
113121
"""
114122
Try to start a named server as defined
@@ -124,11 +132,15 @@ async def start_named_server(
124132
/ server.servername
125133
)
126134
events = []
127-
async with session.post(server_api_url, headers=headers, json=profile_options) as resp:
135+
async with session.post(
136+
server_api_url, headers=headers, json=profile_options
137+
) as resp:
128138
if resp.status == 202:
129139
# we are awaiting start, let's look for events
130140
async with session.get(
131-
server_api_url / "progress", headers=headers, timeout=aiohttp.ClientTimeout(10 * 60)
141+
server_api_url / "progress",
142+
headers=headers,
143+
timeout=aiohttp.ClientTimeout(10 * 60),
132144
) as progress_resp:
133145
async for line in progress_resp.content:
134146
if line.decode().strip() == "":
@@ -145,9 +157,11 @@ async def start_named_server(
145157
hub_access=server.hub_access,
146158
startup_events=events,
147159
server_url=URL(
148-
server.hub_access.url.joinpath(progress_event["url"].lstrip("/"), encoded=True)
160+
server.hub_access.url.joinpath(
161+
progress_event["url"].lstrip("/"), encoded=True
162+
)
149163
),
150-
)
164+
),
151165
)
152166
elif resp.status == 429:
153167
# Sleep for upto roughly 2s and try again
@@ -161,14 +175,16 @@ async def start_named_server(
161175
# Some kinda error
162176
resp.raise_for_status()
163177

178+
164179
def poisson_distribution_wait_times(rate: float, count: int) -> list[float]:
165180
wait_times = []
166181
t = 0
167-
while(len(wait_times) < count):
182+
while len(wait_times) < count:
168183
t += random.expovariate(rate)
169184
wait_times.append(t)
170185
return wait_times
171186

187+
172188
async def payload(
173189
session: aiohttp.ClientSession,
174190
browser: Browser,
@@ -195,23 +211,31 @@ async def payload(
195211
server.servername + ".png",
196212
)
197213
timing_info["nbgitpuller"] = result.duration
198-
print(f"nbgitpuller completed for {server.servername} in {result.duration:0.2f}s")
214+
print(
215+
f"nbgitpuller completed for {server.servername} in {result.duration:0.2f}s"
216+
)
199217
case None:
200218
print("Server startup failed")
201219

202220
print(f"{server.servername}: {timing_info}")
203221

222+
204223
async def delay(duration: float, callable: Coroutine) -> Any:
205224
await asyncio.sleep(duration)
206225
return await callable
207226

227+
208228
async def main():
209229
argparser = argparse.ArgumentParser()
210230
argparser.add_argument("hub_url", help="Full URL to the JupyterHub to test against")
211-
argparser.add_argument("server_prefix", help="Prefix used for named servers started in this run")
231+
argparser.add_argument(
232+
"server_prefix", help="Prefix used for named servers started in this run"
233+
)
212234
argparser.add_argument("username", help="Name of the user")
213235
argparser.add_argument("servers_count", type=int, help="Number of servers to start")
214-
argparser.add_argument("server_startup_rate", type=int, help="Number of servers to start per minute")
236+
argparser.add_argument(
237+
"server_startup_rate", type=int, help="Number of servers to start per minute"
238+
)
215239
# FIXME: This shouldn't be here.
216240
argparser.add_argument(
217241
"--max-concurrency",
@@ -220,36 +244,55 @@ async def main():
220244
help="Max Numbers of Servers to start at the same time",
221245
)
222246
argparser.add_argument(
223-
'--profile-option',
247+
"--profile-option",
224248
help="Additional profile option to specify when starting the server (of key=value form)",
225-
nargs="*"
249+
nargs="*",
226250
)
227251

228252
args = argparser.parse_args()
229253

230-
nbgitpuller_url = NBGitpullerURL("https://github.com/mspass-team/mspass_tutorial/", "master", "Earthscope2025")
254+
nbgitpuller_url = NBGitpullerURL(
255+
"https://github.com/mspass-team/mspass_tutorial/", "master", "Earthscope2025"
256+
)
231257
token = os.environ["JUPYTERHUB_TOKEN"]
232258

233259
profile_options = None
234260
if args.profile_option:
235261
profile_options = {}
236262
for po in args.profile_option:
237-
key, value = po.split('=', 2)
263+
key, value = po.split("=", 2)
238264
profile_options[key] = value
239265

240266
hub_url = URL(args.hub_url)
241267
async with async_playwright() as p:
242268
browser = await p.firefox.launch(headless=False)
243269
async with aiohttp.ClientSession() as session:
244270
servers_to_start = [
245-
Server(f"{args.server_prefix}-{i}", args.username, HubAccess(hub_url, token))
271+
Server(
272+
f"{args.server_prefix}-{i}",
273+
args.username,
274+
HubAccess(hub_url, token),
275+
)
246276
for i in range(args.servers_count)
247277
]
248-
delays = poisson_distribution_wait_times(args.server_startup_rate / 60, args.servers_count)
278+
delays = poisson_distribution_wait_times(
279+
args.server_startup_rate / 60, args.servers_count
280+
)
249281
print(delays)
250282
await aiometer.run_all(
251283
[
252-
partial(delay, duration, payload(session, browser, token, nbgitpuller_url, profile_options, server))
284+
partial(
285+
delay,
286+
duration,
287+
payload(
288+
session,
289+
browser,
290+
token,
291+
nbgitpuller_url,
292+
profile_options,
293+
server,
294+
),
295+
)
253296
for server, duration in zip(servers_to_start, delays)
254297
],
255298
max_at_once=args.max_concurrency,

0 commit comments

Comments
 (0)