dbworkload 0.8.3__tar.gz → 0.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dbworkload-0.8.3 → dbworkload-0.9.0}/PKG-INFO +1 -1
- {dbworkload-0.8.3 → dbworkload-0.9.0}/dbworkload/cli/main.py +4 -1
- {dbworkload-0.8.3 → dbworkload-0.9.0}/dbworkload/models/run.py +22 -15
- {dbworkload-0.8.3 → dbworkload-0.9.0}/pyproject.toml +1 -1
- {dbworkload-0.8.3 → dbworkload-0.9.0}/LICENSE +0 -0
- {dbworkload-0.8.3 → dbworkload-0.9.0}/README.md +0 -0
- {dbworkload-0.8.3 → dbworkload-0.9.0}/dbworkload/__init__.py +0 -0
- {dbworkload-0.8.3 → dbworkload-0.9.0}/dbworkload/cli/dep.py +0 -0
- {dbworkload-0.8.3 → dbworkload-0.9.0}/dbworkload/cli/util.py +0 -0
- {dbworkload-0.8.3 → dbworkload-0.9.0}/dbworkload/models/util.py +0 -0
- {dbworkload-0.8.3 → dbworkload-0.9.0}/dbworkload/templates/stub.j2 +0 -0
- {dbworkload-0.8.3 → dbworkload-0.9.0}/dbworkload/utils/common.py +0 -0
- {dbworkload-0.8.3 → dbworkload-0.9.0}/dbworkload/utils/simplefaker.py +0 -0
|
@@ -16,7 +16,6 @@ import yaml
|
|
|
16
16
|
|
|
17
17
|
import dbworkload.cli.util
|
|
18
18
|
import dbworkload.models.run
|
|
19
|
-
import dbworkload.models.util
|
|
20
19
|
import dbworkload.utils.common
|
|
21
20
|
from dbworkload.cli.dep import EPILOG, ConnInfo, Param
|
|
22
21
|
|
|
@@ -153,6 +152,9 @@ def run(
|
|
|
153
152
|
"--bins",
|
|
154
153
|
help="comma separated list of ints defining the histogram bins.",
|
|
155
154
|
),
|
|
155
|
+
delay_stats: int = typer.Option(
|
|
156
|
+
0, "--delay-stats", help="Start collecting stats after the speciied seconds."
|
|
157
|
+
),
|
|
156
158
|
log_level: LogLevel = Param.LogLevel,
|
|
157
159
|
):
|
|
158
160
|
logger.setLevel(log_level.upper())
|
|
@@ -259,6 +261,7 @@ def run(
|
|
|
259
261
|
save,
|
|
260
262
|
schedule,
|
|
261
263
|
histogram_bins,
|
|
264
|
+
delay_stats,
|
|
262
265
|
log_level.upper(),
|
|
263
266
|
)
|
|
264
267
|
|
|
@@ -15,6 +15,7 @@ from threading import Thread
|
|
|
15
15
|
|
|
16
16
|
import numpy as np
|
|
17
17
|
import tabulate
|
|
18
|
+
from psutil import cpu_percent, virtual_memory
|
|
18
19
|
|
|
19
20
|
import dbworkload.utils.common
|
|
20
21
|
from dbworkload.cli.dep import ConnInfo
|
|
@@ -31,6 +32,7 @@ from dbworkload.cli.dep import ConnInfo
|
|
|
31
32
|
DEFAULT_SLEEP = 3
|
|
32
33
|
MAX_RETRIES = 3
|
|
33
34
|
FREQUENCY = 10
|
|
35
|
+
STATS_BUFFER = 8
|
|
34
36
|
|
|
35
37
|
FIFO = "dbworkload.pipe"
|
|
36
38
|
|
|
@@ -102,7 +104,7 @@ def signal_handler(sig, frame):
|
|
|
102
104
|
sys.exit(1)
|
|
103
105
|
|
|
104
106
|
force_exit = True
|
|
105
|
-
|
|
107
|
+
|
|
106
108
|
# send the poison pill to each proc.
|
|
107
109
|
# if dbworkload cannot graceful shutdown due
|
|
108
110
|
# to processes being still in the init phase
|
|
@@ -187,11 +189,11 @@ def run(
|
|
|
187
189
|
save: bool,
|
|
188
190
|
schedule: list,
|
|
189
191
|
histogram_bins: list,
|
|
192
|
+
delay_stats: int,
|
|
190
193
|
log_level: str,
|
|
191
194
|
):
|
|
192
195
|
def gracefully_shutdown(by_keyinterrupt: bool = False):
|
|
193
|
-
|
|
194
|
-
logger.info("Gracefully shutting down...")
|
|
196
|
+
logger.debug("Gracefully shutting down...")
|
|
195
197
|
|
|
196
198
|
end_time = int(time.time())
|
|
197
199
|
# _s = stats_received
|
|
@@ -208,7 +210,7 @@ def run(
|
|
|
208
210
|
if x.is_alive():
|
|
209
211
|
x.join()
|
|
210
212
|
|
|
211
|
-
# Commenting the below as in theory there shouldn't be any stats that
|
|
213
|
+
# Commenting the below as in theory there shouldn't be any stats that
|
|
212
214
|
# comes in *after* the PROC returns. That is, all threads send stats
|
|
213
215
|
# when all threads are returned, then the supervisor returns.
|
|
214
216
|
# while True:
|
|
@@ -227,7 +229,7 @@ def run(
|
|
|
227
229
|
# break
|
|
228
230
|
|
|
229
231
|
# now that we have all stat reports, calculate the stats one last time.
|
|
230
|
-
report = stats.calculate_stats(active_connections, end_time)
|
|
232
|
+
report = stats.calculate_stats(active_connections, end_time - delay_stats)
|
|
231
233
|
centroids = stats.get_centroids()
|
|
232
234
|
|
|
233
235
|
if save:
|
|
@@ -249,7 +251,7 @@ def run(
|
|
|
249
251
|
|
|
250
252
|
# the final stat report summarizes the entire test run
|
|
251
253
|
final_stats_report = tabulate.tabulate(
|
|
252
|
-
stats.calculate_final_stats(active_connections,
|
|
254
|
+
stats.calculate_final_stats(active_connections, stats.endtime),
|
|
253
255
|
FINAL_HEADERS,
|
|
254
256
|
tablefmt="simple_outline",
|
|
255
257
|
intfmt=",",
|
|
@@ -267,6 +269,7 @@ def run(
|
|
|
267
269
|
["iterations", iterations],
|
|
268
270
|
["ramp", ramp],
|
|
269
271
|
["args", args],
|
|
272
|
+
["delay_stats", delay_stats],
|
|
270
273
|
],
|
|
271
274
|
headers=["Parameter", "Value"],
|
|
272
275
|
)
|
|
@@ -384,10 +387,10 @@ def run(
|
|
|
384
387
|
)
|
|
385
388
|
supervisors[x].start()
|
|
386
389
|
|
|
387
|
-
# report time happens
|
|
390
|
+
# report time happens STATS_BUFFER seconds after the stats are received.
|
|
388
391
|
# we add this buffer to make sure we get all the stats reports
|
|
389
392
|
# from each thread before we aggregate and display
|
|
390
|
-
report_time = start_time + FREQUENCY +
|
|
393
|
+
report_time = start_time + FREQUENCY + STATS_BUFFER + delay_stats
|
|
391
394
|
|
|
392
395
|
returned_procs = 0
|
|
393
396
|
active_connections = 0
|
|
@@ -426,7 +429,7 @@ def run(
|
|
|
426
429
|
ramp_time = dur
|
|
427
430
|
|
|
428
431
|
logger.info(
|
|
429
|
-
f"Starting schedule {i+1}/{len(schedule)}: cc=
|
|
432
|
+
f"Starting schedule {i+1}/{len(schedule)}: {cc=}, {max_rate=}, {ramp_time=}, {dur=}"
|
|
430
433
|
)
|
|
431
434
|
|
|
432
435
|
# always make sure that a duration is specified, even if none was passed
|
|
@@ -488,7 +491,7 @@ def run(
|
|
|
488
491
|
active_connections -= 1
|
|
489
492
|
elif msg == "proc_returned":
|
|
490
493
|
returned_procs += 1
|
|
491
|
-
logger.
|
|
494
|
+
logger.debug(f"Stopped processes: {returned_procs}/{procs} ")
|
|
492
495
|
elif msg == "task_done":
|
|
493
496
|
returned_threads += 1
|
|
494
497
|
except queue.Empty:
|
|
@@ -512,11 +515,15 @@ def run(
|
|
|
512
515
|
sys.exit(1)
|
|
513
516
|
|
|
514
517
|
if time.time() >= report_time:
|
|
515
|
-
|
|
516
|
-
|
|
518
|
+
cpu_util = cpu_percent()
|
|
519
|
+
vmem = virtual_memory().percent
|
|
520
|
+
if stats_received != active_connections or cpu_util > 70 or vmem > 70:
|
|
521
|
+
logger.warning(
|
|
522
|
+
f"{stats_received=}, expected={active_connections}. CPU Util={cpu_util}%, Memory={vmem}%"
|
|
523
|
+
)
|
|
517
524
|
|
|
518
|
-
# remove the
|
|
519
|
-
endtime = int(time.time()) -
|
|
525
|
+
# remove the STATS_BUFFER seconds added
|
|
526
|
+
endtime = int(time.time() - delay_stats) - STATS_BUFFER
|
|
520
527
|
|
|
521
528
|
report = stats.calculate_stats(active_connections, endtime)
|
|
522
529
|
|
|
@@ -591,7 +598,7 @@ def run(
|
|
|
591
598
|
report_time += FREQUENCY
|
|
592
599
|
|
|
593
600
|
# pause briefly to prevent the loop from overheating the CPU
|
|
594
|
-
time.sleep(.001)
|
|
601
|
+
time.sleep(0.001)
|
|
595
602
|
|
|
596
603
|
gracefully_shutdown()
|
|
597
604
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|