(tempdir)
| 4342 | @pytest.mark.parquet |
| 4343 | @pytest.mark.threading |
| 4344 | def test_write_dataset_with_backpressure(tempdir): |
| 4345 | consumer_gate = threading.Event() |
| 4346 | |
| 4347 | # A filesystem that blocks all writes so that we can build |
| 4348 | # up backpressure. The writes are released at the end of |
| 4349 | # the test. |
| 4350 | class GatingFs(ProxyHandler): |
| 4351 | def open_output_stream(self, path, metadata): |
| 4352 | # Block until the end of the test |
| 4353 | consumer_gate.wait() |
| 4354 | return self._fs.open_output_stream(path, metadata=metadata) |
| 4355 | gating_fs = fs.PyFileSystem(GatingFs(fs.LocalFileSystem())) |
| 4356 | |
| 4357 | schema = pa.schema([pa.field('data', pa.int32())]) |
| 4358 | # The scanner should queue ~ 8Mi rows (~8 batches) but due to ARROW-16258 |
| 4359 | # it always queues 32 batches. |
| 4360 | batch = pa.record_batch([pa.array(list(range(1_000_000)))], schema=schema) |
| 4361 | batches_read = 0 |
| 4362 | min_backpressure = 32 |
| 4363 | end = 200 |
| 4364 | keep_going = True |
| 4365 | |
| 4366 | def counting_generator(): |
| 4367 | nonlocal batches_read |
| 4368 | while batches_read < end: |
| 4369 | if not keep_going: |
| 4370 | return |
| 4371 | time.sleep(0.01) |
| 4372 | batches_read += 1 |
| 4373 | yield batch |
| 4374 | |
| 4375 | scanner = ds.Scanner.from_batches( |
| 4376 | counting_generator(), schema=schema, use_threads=True) |
| 4377 | |
| 4378 | write_thread = threading.Thread( |
| 4379 | target=lambda: ds.write_dataset( |
| 4380 | scanner, str(tempdir), format='parquet', filesystem=gating_fs)) |
| 4381 | write_thread.start() |
| 4382 | |
| 4383 | try: |
| 4384 | start = time.time() |
| 4385 | |
| 4386 | def duration(): |
| 4387 | return time.time() - start |
| 4388 | |
| 4389 | # This test is timing dependent. There is no signal from the C++ |
| 4390 | # when backpressure has been hit. We don't know exactly when |
| 4391 | # backpressure will be hit because it may take some time for the |
| 4392 | # signal to get from the sink to the scanner. |
| 4393 | # |
| 4394 | # The test may emit false positives on slow systems. It could |
| 4395 | # theoretically emit a false negative if the scanner managed to read |
| 4396 | # and emit all 200 batches before the backpressure signal had a chance |
| 4397 | # to propagate but the 0.01s delay in the generator should make that |
| 4398 | # scenario unlikely. |
| 4399 | last_value = 0 |
| 4400 | backpressure_probably_hit = False |
| 4401 | while duration() < 10: |
nothing calls this directly
no test coverage detected