redis-benchmarks-specification 0.1.281__py3-none-any.whl → 0.1.282__py3-none-any.whl

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.

Potentially problematic release.


This version of redis-benchmarks-specification might be problematic. Click here for more details.

@@ -19,10 +19,10 @@ import requests
19
19
  def extract_redis_pid(redis_conn) -> Optional[int]:
20
20
  """
21
21
  Extract Redis process ID from Redis INFO command.
22
-
22
+
23
23
  Args:
24
24
  redis_conn: Redis connection object
25
-
25
+
26
26
  Returns:
27
27
  Redis process ID as integer, or None if not found
28
28
  """
@@ -43,10 +43,10 @@ def extract_redis_pid(redis_conn) -> Optional[int]:
43
43
  def extract_redis_metadata(redis_conn) -> Dict[str, Any]:
44
44
  """
45
45
  Extract Redis metadata for profile comments.
46
-
46
+
47
47
  Args:
48
48
  redis_conn: Redis connection object
49
-
49
+
50
50
  Returns:
51
51
  Dictionary containing Redis metadata
52
52
  """
@@ -60,18 +60,20 @@ def extract_redis_metadata(redis_conn) -> Dict[str, Any]:
60
60
  "process_id": redis_info.get("process_id", "unknown"),
61
61
  "tcp_port": redis_info.get("tcp_port", "unknown"),
62
62
  }
63
-
63
+
64
64
  # Use build_id if git_sha1 is empty or 0
65
65
  if metadata["redis_git_sha1"] in ("", 0, "0"):
66
66
  metadata["redis_git_sha1"] = metadata["redis_build_id"]
67
-
68
- logging.info(f"Extracted Redis metadata: version={metadata['redis_version']}, sha={metadata['redis_git_sha1']}, pid={metadata['process_id']}")
67
+
68
+ logging.info(
69
+ f"Extracted Redis metadata: version={metadata['redis_version']}, sha={metadata['redis_git_sha1']}, pid={metadata['process_id']}"
70
+ )
69
71
  return metadata
70
72
  except Exception as e:
71
73
  logging.error(f"Failed to extract Redis metadata: {e}")
72
74
  return {
73
75
  "redis_version": "unknown",
74
- "redis_git_sha1": "unknown",
76
+ "redis_git_sha1": "unknown",
75
77
  "redis_git_dirty": "unknown",
76
78
  "redis_build_id": "unknown",
77
79
  "process_id": "unknown",
@@ -82,16 +84,18 @@ def extract_redis_metadata(redis_conn) -> Dict[str, Any]:
82
84
  def calculate_profile_duration(benchmark_duration_seconds: int) -> int:
83
85
  """
84
86
  Calculate profiling duration based on benchmark duration.
85
-
87
+
86
88
  Args:
87
89
  benchmark_duration_seconds: Expected benchmark duration in seconds
88
-
90
+
89
91
  Returns:
90
92
  Profiling duration in seconds (minimum: benchmark duration, maximum: 30)
91
93
  """
92
94
  # Minimum duration is the benchmark duration, maximum is 30 seconds
93
95
  duration = min(max(benchmark_duration_seconds, 10), 30)
94
- logging.info(f"Calculated profile duration: {duration}s (benchmark: {benchmark_duration_seconds}s)")
96
+ logging.info(
97
+ f"Calculated profile duration: {duration}s (benchmark: {benchmark_duration_seconds}s)"
98
+ )
95
99
  return duration
96
100
 
97
101
 
@@ -102,7 +106,7 @@ def trigger_remote_profile(
102
106
  duration: int,
103
107
  timeout: int = 60,
104
108
  username: Optional[str] = None,
105
- password: Optional[str] = None
109
+ password: Optional[str] = None,
106
110
  ) -> Optional[bytes]:
107
111
  """
108
112
  Trigger remote profiling via HTTP GET request using pprof endpoint.
@@ -120,10 +124,7 @@ def trigger_remote_profile(
120
124
  Profile content in pprof binary format, or None if failed
121
125
  """
122
126
  url = f"http://{host}:{port}/debug/pprof/profile"
123
- params = {
124
- "pid": pid,
125
- "seconds": duration
126
- }
127
+ params = {"pid": pid, "seconds": duration}
127
128
 
128
129
  # Prepare authentication if provided
129
130
  auth = None
@@ -132,7 +133,9 @@ def trigger_remote_profile(
132
133
  logging.info(f"Using HTTP basic authentication with username: {username}")
133
134
 
134
135
  try:
135
- logging.info(f"Triggering remote profile: {url} with PID={pid}, duration={duration}s")
136
+ logging.info(
137
+ f"Triggering remote profile: {url} with PID={pid}, duration={duration}s"
138
+ )
136
139
  response = requests.get(url, params=params, timeout=timeout, auth=auth)
137
140
  response.raise_for_status()
138
141
 
@@ -161,7 +164,7 @@ def save_profile_with_metadata(
161
164
  benchmark_name: str,
162
165
  output_dir: str,
163
166
  redis_metadata: Dict[str, Any],
164
- duration: int
167
+ duration: int,
165
168
  ) -> Optional[str]:
166
169
  """
167
170
  Save profile content to file in pprof binary format.
@@ -188,7 +191,7 @@ def save_profile_with_metadata(
188
191
  timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
189
192
 
190
193
  # Write binary profile content directly
191
- with open(filepath, 'wb') as f:
194
+ with open(filepath, "wb") as f:
192
195
  f.write(profile_content)
193
196
 
194
197
  # Create a separate metadata file
@@ -209,7 +212,7 @@ def save_profile_with_metadata(
209
212
  f"duration_seconds={duration}\n"
210
213
  )
211
214
 
212
- with open(metadata_filepath, 'w') as f:
215
+ with open(metadata_filepath, "w") as f:
213
216
  f.write(metadata_content)
214
217
 
215
218
  logging.info(f"Saved profile to: {filepath}")
@@ -226,7 +229,14 @@ class RemoteProfiler:
226
229
  Remote profiler class to handle threaded profiling execution.
227
230
  """
228
231
 
229
- def __init__(self, host: str, port: int, output_dir: str, username: Optional[str] = None, password: Optional[str] = None):
232
+ def __init__(
233
+ self,
234
+ host: str,
235
+ port: int,
236
+ output_dir: str,
237
+ username: Optional[str] = None,
238
+ password: Optional[str] = None,
239
+ ):
230
240
  self.host = host
231
241
  self.port = port
232
242
  self.output_dir = output_dir
@@ -235,21 +245,18 @@ class RemoteProfiler:
235
245
  self.profile_thread = None
236
246
  self.profile_result = None
237
247
  self.profile_error = None
238
-
248
+
239
249
  def start_profiling(
240
- self,
241
- redis_conn,
242
- benchmark_name: str,
243
- benchmark_duration_seconds: int
250
+ self, redis_conn, benchmark_name: str, benchmark_duration_seconds: int
244
251
  ) -> bool:
245
252
  """
246
253
  Start profiling in a separate thread.
247
-
254
+
248
255
  Args:
249
256
  redis_conn: Redis connection object
250
257
  benchmark_name: Name of the benchmark
251
258
  benchmark_duration_seconds: Expected benchmark duration
252
-
259
+
253
260
  Returns:
254
261
  True if profiling thread started successfully, False otherwise
255
262
  """
@@ -257,44 +264,60 @@ class RemoteProfiler:
257
264
  # Extract Redis metadata and PID
258
265
  redis_metadata = extract_redis_metadata(redis_conn)
259
266
  pid = redis_metadata.get("process_id")
260
-
267
+
261
268
  if pid == "unknown" or pid is None:
262
269
  logging.error("Cannot start remote profiling: Redis PID not available")
263
270
  return False
264
-
271
+
265
272
  # Calculate profiling duration
266
273
  duration = calculate_profile_duration(benchmark_duration_seconds)
267
-
274
+
268
275
  # Start profiling thread
269
276
  self.profile_thread = threading.Thread(
270
277
  target=self._profile_worker,
271
278
  args=(pid, duration, benchmark_name, redis_metadata),
272
- daemon=True
279
+ daemon=True,
273
280
  )
274
281
  self.profile_thread.start()
275
-
276
- logging.info(f"Started remote profiling thread for benchmark: {benchmark_name}")
282
+
283
+ logging.info(
284
+ f"Started remote profiling thread for benchmark: {benchmark_name}"
285
+ )
277
286
  return True
278
-
287
+
279
288
  except Exception as e:
280
289
  logging.error(f"Failed to start remote profiling: {e}")
281
290
  return False
282
-
283
- def _profile_worker(self, pid: int, duration: int, benchmark_name: str, redis_metadata: Dict[str, Any]):
291
+
292
+ def _profile_worker(
293
+ self,
294
+ pid: int,
295
+ duration: int,
296
+ benchmark_name: str,
297
+ redis_metadata: Dict[str, Any],
298
+ ):
284
299
  """
285
300
  Worker function for profiling thread.
286
301
  """
287
302
  try:
288
303
  # Trigger remote profiling
289
304
  profile_content = trigger_remote_profile(
290
- self.host, self.port, pid, duration,
291
- username=self.username, password=self.password
305
+ self.host,
306
+ self.port,
307
+ pid,
308
+ duration,
309
+ username=self.username,
310
+ password=self.password,
292
311
  )
293
312
 
294
313
  if profile_content is not None:
295
314
  # Save profile with metadata
296
315
  filepath = save_profile_with_metadata(
297
- profile_content, benchmark_name, self.output_dir, redis_metadata, duration
316
+ profile_content,
317
+ benchmark_name,
318
+ self.output_dir,
319
+ redis_metadata,
320
+ duration,
298
321
  )
299
322
  self.profile_result = filepath
300
323
  else:
@@ -303,38 +326,42 @@ class RemoteProfiler:
303
326
  except Exception as e:
304
327
  self.profile_error = f"Profile worker error: {e}"
305
328
  logging.error(self.profile_error)
306
-
329
+
307
330
  def wait_for_completion(self, timeout: int = 60) -> bool:
308
331
  """
309
332
  Wait for profiling thread to complete.
310
-
333
+
311
334
  Args:
312
335
  timeout: Maximum time to wait in seconds
313
-
336
+
314
337
  Returns:
315
338
  True if completed successfully, False if timed out or failed
316
339
  """
317
340
  if self.profile_thread is None:
318
341
  return False
319
-
342
+
320
343
  try:
321
344
  self.profile_thread.join(timeout=timeout)
322
-
345
+
323
346
  if self.profile_thread.is_alive():
324
- logging.warning(f"Remote profiling thread did not complete within {timeout}s")
347
+ logging.warning(
348
+ f"Remote profiling thread did not complete within {timeout}s"
349
+ )
325
350
  return False
326
-
351
+
327
352
  if self.profile_error:
328
353
  logging.error(f"Remote profiling failed: {self.profile_error}")
329
354
  return False
330
-
355
+
331
356
  if self.profile_result:
332
- logging.info(f"Remote profiling completed successfully: {self.profile_result}")
357
+ logging.info(
358
+ f"Remote profiling completed successfully: {self.profile_result}"
359
+ )
333
360
  return True
334
361
  else:
335
362
  logging.warning("Remote profiling completed but no result available")
336
363
  return False
337
-
364
+
338
365
  except Exception as e:
339
366
  logging.error(f"Error waiting for remote profiling completion: {e}")
340
367
  return False