deltacat 1.1.18__py3-none-any.whl → 1.1.20__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.
Files changed (53) hide show
  1. deltacat/__init__.py +1 -1
  2. deltacat/compute/compactor/model/compact_partition_params.py +76 -0
  3. deltacat/compute/compactor/model/compaction_session_audit_info.py +26 -0
  4. deltacat/compute/compactor/model/delta_annotated.py +16 -9
  5. deltacat/compute/compactor_v2/constants.py +3 -0
  6. deltacat/compute/compactor_v2/private/compaction_utils.py +11 -5
  7. deltacat/compute/compactor_v2/utils/content_type_params.py +185 -34
  8. deltacat/compute/compactor_v2/utils/io.py +28 -14
  9. deltacat/compute/compactor_v2/utils/task_options.py +128 -183
  10. deltacat/compute/resource_estimation/__init__.py +27 -0
  11. deltacat/compute/resource_estimation/delta.py +271 -0
  12. deltacat/compute/resource_estimation/manifest.py +394 -0
  13. deltacat/compute/resource_estimation/model.py +165 -0
  14. deltacat/compute/resource_estimation/parquet.py +108 -0
  15. deltacat/constants.py +5 -0
  16. deltacat/logs.py +8 -0
  17. deltacat/tests/compute/compactor_v2/test_compaction_session.py +157 -0
  18. deltacat/tests/compute/compactor_v2/utils/test_task_options.py +3 -3
  19. deltacat/tests/compute/resource_estimation/test_delta.py +605 -0
  20. deltacat/tests/compute/resource_estimation/test_manifest.py +921 -0
  21. deltacat/tests/compute/test_util_common.py +2 -0
  22. deltacat/tests/test_logs.py +34 -0
  23. deltacat/tests/test_utils/pyarrow.py +15 -5
  24. {deltacat-1.1.18.dist-info → deltacat-1.1.20.dist-info}/METADATA +2 -2
  25. {deltacat-1.1.18.dist-info → deltacat-1.1.20.dist-info}/RECORD +30 -46
  26. deltacat/compute/metastats/meta_stats.py +0 -479
  27. deltacat/compute/metastats/model/__init__.py +0 -0
  28. deltacat/compute/metastats/model/partition_stats_dict.py +0 -34
  29. deltacat/compute/metastats/model/stats_cluster_size_estimator.py +0 -68
  30. deltacat/compute/metastats/stats.py +0 -182
  31. deltacat/compute/metastats/utils/__init__.py +0 -0
  32. deltacat/compute/metastats/utils/constants.py +0 -16
  33. deltacat/compute/metastats/utils/io.py +0 -223
  34. deltacat/compute/metastats/utils/pyarrow_memory_estimation_function.py +0 -18
  35. deltacat/compute/metastats/utils/ray_utils.py +0 -129
  36. deltacat/compute/stats/basic.py +0 -226
  37. deltacat/compute/stats/models/__init__.py +0 -0
  38. deltacat/compute/stats/models/delta_column_stats.py +0 -98
  39. deltacat/compute/stats/models/delta_stats.py +0 -233
  40. deltacat/compute/stats/models/delta_stats_cache_result.py +0 -49
  41. deltacat/compute/stats/models/manifest_entry_stats.py +0 -72
  42. deltacat/compute/stats/models/stats_result.py +0 -104
  43. deltacat/compute/stats/utils/__init__.py +0 -0
  44. deltacat/compute/stats/utils/intervals.py +0 -94
  45. deltacat/compute/stats/utils/io.py +0 -230
  46. deltacat/compute/stats/utils/manifest_stats_file.py +0 -100
  47. deltacat/tests/stats/__init__.py +0 -0
  48. deltacat/tests/stats/test_intervals.py +0 -49
  49. /deltacat/{compute/metastats → tests/compute/resource_estimation}/__init__.py +0 -0
  50. /deltacat/{compute/metastats/config → tests/compute/resource_estimation/data}/__init__.py +0 -0
  51. {deltacat-1.1.18.dist-info → deltacat-1.1.20.dist-info}/LICENSE +0 -0
  52. {deltacat-1.1.18.dist-info → deltacat-1.1.20.dist-info}/WHEEL +0 -0
  53. {deltacat-1.1.18.dist-info → deltacat-1.1.20.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,165 @@
1
+ from __future__ import annotations
2
+ from enum import Enum
3
+ from typing import Optional
4
+
5
+
6
+ class ResourceEstimationMethod(str, Enum):
7
+ """
8
+ The default approach executes certain methods in a specific order until the size
9
+ is estimated by any. The order is as follows:
10
+ 1. CONTENT_TYPE_META
11
+ 2. PREVIOUS_INFLATION
12
+ This method expects previous inflation and average record bytes to be passed.
13
+ """
14
+
15
+ DEFAULT = "DEFAULT"
16
+
17
+ """
18
+ This approach combines intelligent estimation and inflation based methods
19
+ and runs them in the order specified below:
20
+ 1. INTELLIGENT_ESTIMATION
21
+ 2. FILE_SAMPLING
22
+ 3. PREVIOUS_INFLATION
23
+ """
24
+ DEFAULT_V2 = "DEFAULT_V2"
25
+
26
+ """
27
+ This approach strictly uses previous inflation and average record size to arrive
28
+ at a resource estimate. It requires users to pass in previous inflation and average
29
+ record sizes.
30
+ """
31
+ PREVIOUS_INFLATION = "PREVIOUS_INFLATION"
32
+
33
+ """
34
+ This approach is similar to PREVIOUS_INFLATION, but it determines average record size
35
+ and previous inflation by sampling few files in the given set of files.
36
+ """
37
+ FILE_SAMPLING = "FILE_SAMPLING"
38
+
39
+ """
40
+ This approach leverages metadata present in content type params.
41
+ """
42
+ CONTENT_TYPE_META = "CONTENT_TYPE_META"
43
+
44
+ """
45
+ This approach leverages parquet metadata and granularly estimate resources for each column and
46
+ then aggregate to arrive at most accurate estimation.
47
+ """
48
+ INTELLIGENT_ESTIMATION = "INTELLIGENT_ESTIMATION"
49
+
50
+
51
+ class EstimateResourcesParams(dict):
52
+ """
53
+ This class represents the parameters required for estimating resources.
54
+ """
55
+
56
+ @staticmethod
57
+ def of(
58
+ resource_estimation_method: ResourceEstimationMethod = ResourceEstimationMethod.DEFAULT,
59
+ previous_inflation: Optional[float] = None,
60
+ parquet_to_pyarrow_inflation: Optional[float] = None,
61
+ average_record_size_bytes: Optional[float] = None,
62
+ max_files_to_sample: Optional[int] = None,
63
+ ) -> EstimateResourcesParams:
64
+ result = EstimateResourcesParams()
65
+ result["previous_inflation"] = previous_inflation
66
+ result["parquet_to_pyarrow_inflation"] = parquet_to_pyarrow_inflation
67
+ result["resource_estimation_method"] = resource_estimation_method
68
+ result["max_files_to_sample"] = max_files_to_sample
69
+ result["average_record_size_bytes"] = average_record_size_bytes
70
+ return result
71
+
72
+ @property
73
+ def resource_estimation_method(self) -> ResourceEstimationMethod:
74
+ return self["resource_estimation_method"]
75
+
76
+ @property
77
+ def max_files_to_sample(self) -> Optional[int]:
78
+ """
79
+ Applicable only for FILE_SAMPLING method. This parameter controls the
80
+ number of files to sample to arrive at average record sizes and previous inflation.
81
+ """
82
+ return self.get("max_files_to_sample")
83
+
84
+ @property
85
+ def previous_inflation(self) -> Optional[float]:
86
+ """
87
+ This parameter is required for PREVIOUS_INFLATION method. The inflation factor determines
88
+ a ratio of in-memory size to the on-disk size.
89
+ """
90
+ return self.get("previous_inflation")
91
+
92
+ @property
93
+ def parquet_to_pyarrow_inflation(self) -> Optional[float]:
94
+ """
95
+ This parameter is required for INTELLIGENT_ESTIMATION or CONTENT_TYPE_META method.
96
+ This determines inflation factor for parquet estimated size to pyarrow in-memory table size.
97
+ """
98
+ return self.get("parquet_to_pyarrow_inflation")
99
+
100
+ @property
101
+ def average_record_size_bytes(self) -> Optional[float]:
102
+ """
103
+ This parameter is required for PREVIOUS_INFLATION method. This determines average size of
104
+ records in bytes in a given file or entity.
105
+ """
106
+ return self.get("average_record_size_bytes")
107
+
108
+
109
+ class OperationType(str, Enum):
110
+ """
111
+ This operation type is used when user would download the given entities using pyarrow library.
112
+ """
113
+
114
+ PYARROW_DOWNLOAD = "DOWNLOAD"
115
+
116
+
117
+ class EstimatedResources(dict):
118
+ """
119
+ This class represents the resource requirements for a certain type of operation.
120
+ For example, downloading a delta requires certain amount of memory.
121
+ """
122
+
123
+ @staticmethod
124
+ def of(memory_bytes: float, statistics: Statistics = None) -> EstimatedResources:
125
+ result = EstimatedResources()
126
+ result["memory_bytes"] = memory_bytes
127
+ result["statistics"] = statistics
128
+ return result
129
+
130
+ @property
131
+ def memory_bytes(self) -> float:
132
+ return self["memory_bytes"]
133
+
134
+ @property
135
+ def statistics(self) -> Optional[Statistics]:
136
+ return self.get("statistics")
137
+
138
+
139
+ class Statistics(dict):
140
+ """
141
+ This class represents the statistics of underlying objects that was used
142
+ to estimate the resource required.
143
+ """
144
+
145
+ @staticmethod
146
+ def of(
147
+ in_memory_size_bytes: float, record_count: int, on_disk_size_bytes: float
148
+ ) -> Statistics:
149
+ result = Statistics()
150
+ result["in_memory_size_bytes"] = in_memory_size_bytes
151
+ result["record_count"] = record_count
152
+ result["on_disk_size_bytes"] = on_disk_size_bytes
153
+ return result
154
+
155
+ @property
156
+ def in_memory_size_bytes(self) -> float:
157
+ return self["in_memory_size_bytes"]
158
+
159
+ @property
160
+ def record_count(self) -> int:
161
+ return self["record_count"]
162
+
163
+ @property
164
+ def on_disk_size_bytes(self) -> float:
165
+ return self["on_disk_size_bytes"]
@@ -0,0 +1,108 @@
1
+ import logging
2
+ from typing import Optional
3
+ from deltacat import logs
4
+ from pyarrow.parquet import ColumnChunkMetaData
5
+ from deltacat.constants import NULL_SIZE_BYTES
6
+
7
+ logger = logs.configure_deltacat_logger(logging.getLogger(__name__))
8
+
9
+
10
+ def _observed_string_size(min_value: str, max_value: str) -> float:
11
+ """
12
+ Pyarrow uses few additional bytes to store each string.
13
+ """
14
+ return (len(min_value) + len(max_value)) / 2 + 4
15
+
16
+
17
+ def _int96_size_estimator(
18
+ column_chunk_metadata: ColumnChunkMetaData,
19
+ ) -> float:
20
+ return column_chunk_metadata.num_values * 12
21
+
22
+
23
+ def _int64_size_estimator(
24
+ column_chunk_metadata: ColumnChunkMetaData,
25
+ ) -> float:
26
+ return column_chunk_metadata.num_values * 8
27
+
28
+
29
+ def _int32_size_estimator(
30
+ column_chunk_metadata: ColumnChunkMetaData,
31
+ ) -> float:
32
+ return column_chunk_metadata.num_values * 4
33
+
34
+
35
+ def _boolean_size_estimator(
36
+ column_chunk_metadata: ColumnChunkMetaData,
37
+ ) -> float:
38
+ return column_chunk_metadata.num_values
39
+
40
+
41
+ def _double_size_estimator(
42
+ column_chunk_metadata: ColumnChunkMetaData,
43
+ ) -> float:
44
+ return column_chunk_metadata.num_values * 8
45
+
46
+
47
+ def _float_size_estimator(
48
+ column_chunk_metadata: ColumnChunkMetaData,
49
+ ) -> float:
50
+ return column_chunk_metadata.num_values * 4
51
+
52
+
53
+ def _byte_array_size_estimator(
54
+ column_chunk_metadata: ColumnChunkMetaData,
55
+ ) -> float:
56
+ uncompressed_size = column_chunk_metadata.total_uncompressed_size
57
+ if column_chunk_metadata.is_stats_set:
58
+ statistics = column_chunk_metadata.statistics
59
+ if (
60
+ statistics.has_min_max
61
+ and isinstance(statistics.min, str)
62
+ and isinstance(statistics.max, str)
63
+ ):
64
+ return max(
65
+ uncompressed_size,
66
+ (
67
+ statistics.num_values
68
+ * _observed_string_size(statistics.min, statistics.max)
69
+ + statistics.null_count * NULL_SIZE_BYTES
70
+ ),
71
+ )
72
+ else:
73
+ # A case of decimal
74
+ return max(column_chunk_metadata.num_values * 16, uncompressed_size)
75
+ else:
76
+ return uncompressed_size
77
+
78
+
79
+ def _fixed_len_byte_array_size_estimator(
80
+ column_chunk_metadata: ColumnChunkMetaData,
81
+ ) -> float:
82
+ return _byte_array_size_estimator(column_chunk_metadata)
83
+
84
+
85
+ _PHYSICAL_TYPE_TO_SIZE_ESTIMATOR = {
86
+ "INT96": _int96_size_estimator,
87
+ "INT64": _int64_size_estimator,
88
+ "INT32": _int32_size_estimator,
89
+ "BOOLEAN": _boolean_size_estimator,
90
+ "DOUBLE": _double_size_estimator,
91
+ "FLOAT": _float_size_estimator,
92
+ "BYTE_ARRAY": _byte_array_size_estimator,
93
+ "FIXED_LEN_BYTE_ARRAY": _fixed_len_byte_array_size_estimator,
94
+ }
95
+
96
+
97
+ def parquet_column_chunk_size_estimator(
98
+ column_meta: ColumnChunkMetaData,
99
+ ) -> Optional[float]:
100
+ physical_type = column_meta.physical_type
101
+ if physical_type in _PHYSICAL_TYPE_TO_SIZE_ESTIMATOR:
102
+ return _PHYSICAL_TYPE_TO_SIZE_ESTIMATOR[physical_type](column_meta)
103
+ else:
104
+ logger.warning(
105
+ f"Unsupported physical type: {physical_type}. "
106
+ "Returning total_uncompressed_size."
107
+ )
108
+ return column_meta.total_uncompressed_size
deltacat/constants.py CHANGED
@@ -28,6 +28,8 @@ DELTACAT_APP_DEBUG_LOG_BASE_FILE_NAME = env_string(
28
28
  "DELTACAT_APP_DEBUG_LOG_BASE_FILE_NAME",
29
29
  "application.debug.log",
30
30
  )
31
+ # A json context which will be logged along with other context args.
32
+ DELTACAT_LOGGER_CONTEXT = env_string("DELTACAT_LOGGER_CONTEXT", None)
31
33
 
32
34
  # Byte Units
33
35
  BYTES_PER_KIBIBYTE = 2**10
@@ -53,3 +55,6 @@ PYARROW_INFLATION_MULTIPLIER = 2.5
53
55
  PYARROW_INFLATION_MULTIPLIER_ALL_COLUMNS = 6
54
56
 
55
57
  MEMORY_TO_HASH_BUCKET_COUNT_RATIO = 0.0512 * BYTES_PER_TEBIBYTE
58
+
59
+ # The number of bytes allocated to null values in string physical type in parquet
60
+ NULL_SIZE_BYTES = 4
deltacat/logs.py CHANGED
@@ -17,6 +17,7 @@ from deltacat.constants import (
17
17
  DELTACAT_SYS_INFO_LOG_BASE_FILE_NAME,
18
18
  DELTACAT_APP_DEBUG_LOG_BASE_FILE_NAME,
19
19
  DELTACAT_SYS_DEBUG_LOG_BASE_FILE_NAME,
20
+ DELTACAT_LOGGER_CONTEXT,
20
21
  )
21
22
 
22
23
  DEFAULT_LOG_LEVEL = "INFO"
@@ -66,6 +67,13 @@ class JsonFormatter(logging.Formatter):
66
67
  self.ray_runtime_ctx = None
67
68
  self.context = {}
68
69
 
70
+ if DELTACAT_LOGGER_CONTEXT is not None:
71
+ try:
72
+ env_context = json.loads(DELTACAT_LOGGER_CONTEXT)
73
+ self.additional_context.update(env_context)
74
+ except Exception:
75
+ pass
76
+
69
77
  def usesTime(self) -> bool:
70
78
  """
71
79
  Overwritten to look for the attribute in the format dict values instead of the fmt string.
@@ -19,6 +19,7 @@ from deltacat.tests.test_utils.utils import read_s3_contents
19
19
  from deltacat.tests.compute.test_util_constant import (
20
20
  TEST_S3_RCF_BUCKET_NAME,
21
21
  )
22
+ from deltacat.compute.resource_estimation import ResourceEstimationMethod
22
23
  from deltacat.tests.compute.test_util_common import get_rcf
23
24
  from deltacat.tests.test_utils.pyarrow import (
24
25
  stage_partition_from_file_paths,
@@ -399,3 +400,159 @@ class TestCompactionSession:
399
400
  assert compaction_audit.output_file_count == 2
400
401
  assert abs(compaction_audit.output_size_bytes - 1843) / 1843 <= self.ERROR_RATE
401
402
  assert abs(compaction_audit.input_size_bytes - 2748) / 2748 <= self.ERROR_RATE
403
+
404
+ def test_compact_partition_when_incremental_then_intelligent_estimation_sanity(
405
+ self, s3_resource, local_deltacat_storage_kwargs
406
+ ):
407
+ """
408
+ A test case which asserts the RCF stats are correctly generated for
409
+ a rebase and incremental use-case.
410
+ """
411
+
412
+ # setup
413
+ staged_source = stage_partition_from_file_paths(
414
+ self.NAMESPACE, ["source"], **local_deltacat_storage_kwargs
415
+ )
416
+
417
+ source_delta = commit_delta_to_staged_partition(
418
+ staged_source, [self.BACKFILL_FILE_PATH], **local_deltacat_storage_kwargs
419
+ )
420
+
421
+ staged_dest = stage_partition_from_file_paths(
422
+ self.NAMESPACE, ["destination"], **local_deltacat_storage_kwargs
423
+ )
424
+ dest_partition = ds.commit_partition(
425
+ staged_dest, **local_deltacat_storage_kwargs
426
+ )
427
+
428
+ # action
429
+ compact_partition(
430
+ CompactPartitionParams.of(
431
+ {
432
+ "compaction_artifact_s3_bucket": TEST_S3_RCF_BUCKET_NAME,
433
+ "compacted_file_content_type": ContentType.PARQUET,
434
+ "dd_max_parallelism_ratio": 1.0,
435
+ "deltacat_storage": ds,
436
+ "deltacat_storage_kwargs": local_deltacat_storage_kwargs,
437
+ "destination_partition_locator": dest_partition.locator,
438
+ "drop_duplicates": True,
439
+ "hash_bucket_count": 2,
440
+ "last_stream_position_to_compact": source_delta.stream_position,
441
+ "list_deltas_kwargs": {
442
+ **local_deltacat_storage_kwargs,
443
+ **{"equivalent_table_types": []},
444
+ },
445
+ "primary_keys": ["pk"],
446
+ "rebase_source_partition_locator": source_delta.partition_locator,
447
+ "rebase_source_partition_high_watermark": source_delta.stream_position,
448
+ "records_per_compacted_file": 4000,
449
+ "s3_client_kwargs": {},
450
+ "source_partition_locator": source_delta.partition_locator,
451
+ "resource_estimation_method": ResourceEstimationMethod.INTELLIGENT_ESTIMATION,
452
+ }
453
+ )
454
+ )
455
+
456
+ def test_compact_partition_when_incremental_then_content_type_meta_estimation_sanity(
457
+ self, s3_resource, local_deltacat_storage_kwargs
458
+ ):
459
+ """
460
+ A test case which asserts the RCF stats are correctly generated for
461
+ a rebase and incremental use-case.
462
+ """
463
+
464
+ # setup
465
+ staged_source = stage_partition_from_file_paths(
466
+ self.NAMESPACE, ["source"], **local_deltacat_storage_kwargs
467
+ )
468
+
469
+ source_delta = commit_delta_to_staged_partition(
470
+ staged_source, [self.BACKFILL_FILE_PATH], **local_deltacat_storage_kwargs
471
+ )
472
+
473
+ staged_dest = stage_partition_from_file_paths(
474
+ self.NAMESPACE, ["destination"], **local_deltacat_storage_kwargs
475
+ )
476
+ dest_partition = ds.commit_partition(
477
+ staged_dest, **local_deltacat_storage_kwargs
478
+ )
479
+
480
+ # action
481
+ compact_partition(
482
+ CompactPartitionParams.of(
483
+ {
484
+ "compaction_artifact_s3_bucket": TEST_S3_RCF_BUCKET_NAME,
485
+ "compacted_file_content_type": ContentType.PARQUET,
486
+ "dd_max_parallelism_ratio": 1.0,
487
+ "deltacat_storage": ds,
488
+ "deltacat_storage_kwargs": local_deltacat_storage_kwargs,
489
+ "destination_partition_locator": dest_partition.locator,
490
+ "drop_duplicates": True,
491
+ "hash_bucket_count": 2,
492
+ "last_stream_position_to_compact": source_delta.stream_position,
493
+ "list_deltas_kwargs": {
494
+ **local_deltacat_storage_kwargs,
495
+ **{"equivalent_table_types": []},
496
+ },
497
+ "primary_keys": ["pk"],
498
+ "rebase_source_partition_locator": source_delta.partition_locator,
499
+ "rebase_source_partition_high_watermark": source_delta.stream_position,
500
+ "records_per_compacted_file": 4000,
501
+ "s3_client_kwargs": {},
502
+ "source_partition_locator": source_delta.partition_locator,
503
+ "resource_estimation_method": ResourceEstimationMethod.CONTENT_TYPE_META,
504
+ }
505
+ )
506
+ )
507
+
508
+ def test_compact_partition_when_incremental_then_previous_inflation_estimation_sanity(
509
+ self, s3_resource, local_deltacat_storage_kwargs
510
+ ):
511
+ """
512
+ A test case which asserts the RCF stats are correctly generated for
513
+ a rebase and incremental use-case.
514
+ """
515
+
516
+ # setup
517
+ staged_source = stage_partition_from_file_paths(
518
+ self.NAMESPACE, ["source"], **local_deltacat_storage_kwargs
519
+ )
520
+
521
+ source_delta = commit_delta_to_staged_partition(
522
+ staged_source, [self.BACKFILL_FILE_PATH], **local_deltacat_storage_kwargs
523
+ )
524
+
525
+ staged_dest = stage_partition_from_file_paths(
526
+ self.NAMESPACE, ["destination"], **local_deltacat_storage_kwargs
527
+ )
528
+ dest_partition = ds.commit_partition(
529
+ staged_dest, **local_deltacat_storage_kwargs
530
+ )
531
+
532
+ # action
533
+ compact_partition(
534
+ CompactPartitionParams.of(
535
+ {
536
+ "compaction_artifact_s3_bucket": TEST_S3_RCF_BUCKET_NAME,
537
+ "compacted_file_content_type": ContentType.PARQUET,
538
+ "dd_max_parallelism_ratio": 1.0,
539
+ "deltacat_storage": ds,
540
+ "deltacat_storage_kwargs": local_deltacat_storage_kwargs,
541
+ "destination_partition_locator": dest_partition.locator,
542
+ "drop_duplicates": True,
543
+ "hash_bucket_count": 2,
544
+ "last_stream_position_to_compact": source_delta.stream_position,
545
+ "list_deltas_kwargs": {
546
+ **local_deltacat_storage_kwargs,
547
+ **{"equivalent_table_types": []},
548
+ },
549
+ "primary_keys": ["pk"],
550
+ "rebase_source_partition_locator": source_delta.partition_locator,
551
+ "rebase_source_partition_high_watermark": source_delta.stream_position,
552
+ "records_per_compacted_file": 4000,
553
+ "s3_client_kwargs": {},
554
+ "source_partition_locator": source_delta.partition_locator,
555
+ "resource_estimation_method": ResourceEstimationMethod.PREVIOUS_INFLATION,
556
+ }
557
+ )
558
+ )
@@ -1,6 +1,6 @@
1
1
  import unittest
2
2
  import ray
3
- from deltacat.compute.compactor_v2.utils.task_options import get_task_options
3
+ from deltacat.compute.compactor_v2.utils.task_options import _get_task_options
4
4
 
5
5
 
6
6
  @ray.remote
@@ -20,14 +20,14 @@ class TestTaskOptions(unittest.TestCase):
20
20
  super().setUpClass()
21
21
 
22
22
  def test_get_task_options_sanity(self):
23
- opts = get_task_options(0.01, 0.01)
23
+ opts = _get_task_options(0.01, 0.01)
24
24
  result_ref = valid_func.options(**opts).remote()
25
25
  result = ray.get(result_ref)
26
26
 
27
27
  self.assertEqual(result, 2)
28
28
 
29
29
  def test_get_task_options_when_exception_is_thrown(self):
30
- opts = get_task_options(0.01, 0.01)
30
+ opts = _get_task_options(0.01, 0.01)
31
31
  result_ref = throwing_func.options(**opts).remote()
32
32
 
33
33
  self.assertRaises(ConnectionAbortedError, lambda: ray.get(result_ref))