From 45f5d7ebf5ee13be6c7030270b57c21910187fc8 Mon Sep 17 00:00:00 2001
From: sebastianMindee <130448732+sebastianMindee@users.noreply.github.com>
Date: Mon, 10 Nov 2025 13:58:18 +0100
Subject: [PATCH 01/12] :bug: fix sleep timers not properly taking floats into
account
---
phpcs.xml | 53 +---------------------------
src/Client.php | 8 +++--
src/ClientUtilityMixin.php | 27 +++++++++++++++
src/ClientV2.php | 6 ++--
src/Parsing/Common/Job.php | 6 +++-
tests/ClientUtilityMixinTest.php | 59 ++++++++++++++++++++++++++++++++
6 files changed, 101 insertions(+), 58 deletions(-)
create mode 100644 src/ClientUtilityMixin.php
create mode 100644 tests/ClientUtilityMixinTest.php
diff --git a/phpcs.xml b/phpcs.xml
index bd548b7a..31de617e 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -23,12 +23,6 @@
-
-
-
-
-
-
@@ -117,13 +111,6 @@
-
-
-
-
-
-
-
@@ -135,16 +122,8 @@
-
-
-
-
-
-
-
-
+
@@ -155,15 +134,6 @@
-
-
-
- error
- Method name "%s" must not be prefixed with an underscore to indicate visibility
-
-
-
-
@@ -196,20 +166,12 @@
-
-
-
- 0
-
-
- 0
-
@@ -251,8 +213,6 @@
-
-
@@ -261,9 +221,6 @@
-
-
-
@@ -292,14 +249,6 @@
-
-
- 0
-
-
- 0
-
-
diff --git a/src/Client.php b/src/Client.php
index 70eb9674..3e652720 100644
--- a/src/Client.php
+++ b/src/Client.php
@@ -43,6 +43,8 @@
*/
class Client
{
+ use ClientUtilityMixin;
+
/**
* Default owner for API products.
*
@@ -463,7 +465,7 @@ public function enqueueAndParse(
);
error_log("Successfully enqueued document with job id: " . $enqueueResponse->job->id);
- sleep($asyncOptions->initialDelaySec);
+ $this->customSleep($asyncOptions->initialDelaySec);
$retryCounter = 1;
$pollResults = $this->parseQueued($predictionType, $enqueueResponse->job->id, $options->endpoint);
@@ -473,7 +475,7 @@ public function enqueueAndParse(
}
error_log("Polling server for parsing result with job id: " . $enqueueResponse->job->id);
$retryCounter++;
- sleep($asyncOptions->delaySec);
+ $this->customSleep($asyncOptions->delaySec);
$pollResults = $this->parseQueued($predictionType, $enqueueResponse->job->id, $options->endpoint);
}
if ($pollResults->job->status != "completed") {
@@ -540,7 +542,7 @@ public function parseQueued(
public function loadPrediction(
string $predictionType,
LocalResponse $localResponse
- ) {
+ ): AsyncPredictResponse|PredictResponse {
try {
$json = $localResponse->toArray();
if (isset($json['job'])) {
diff --git a/src/ClientUtilityMixin.php b/src/ClientUtilityMixin.php
new file mode 100644
index 00000000..6a89db19
--- /dev/null
+++ b/src/ClientUtilityMixin.php
@@ -0,0 +1,27 @@
+ 0) {
+ sleep($delay);
+ }
+ if ($micros > 0) {
+ usleep($micros * 1_000_000);
+ }
+ }
+}
diff --git a/src/ClientV2.php b/src/ClientV2.php
index 50d34401..b74fd081 100644
--- a/src/ClientV2.php
+++ b/src/ClientV2.php
@@ -14,6 +14,8 @@
*/
class ClientV2
{
+ use ClientUtilityMixin;
+
/**
* @var MindeeApiV2 Mindee API V2.
*/
@@ -96,7 +98,7 @@ public function enqueueAndGetInference(
$queueId = $enqueueResponse->job->id;
error_log("Successfully enqueued document with job id: " . $queueId);
- sleep($pollingOptions->initialDelaySec);
+ $this->customSleep($pollingOptions->initialDelaySec);
$retryCounter = 1;
$pollResults = $this->getJob($queueId);
@@ -114,7 +116,7 @@ public function enqueueAndGetInference(
". Job status: " . $pollResults->job->status
);
- sleep($pollingOptions->delaySec);
+ $this->customSleep($pollingOptions->delaySec);
$pollResults = $this->getJob($queueId);
$retryCounter++;
}
diff --git a/src/Parsing/Common/Job.php b/src/Parsing/Common/Job.php
index bd428e26..3bc4e949 100644
--- a/src/Parsing/Common/Job.php
+++ b/src/Parsing/Common/Job.php
@@ -37,6 +37,7 @@ class Job
* @var array|null Information about an error that occurred during the job processing.
*/
public ?array $error;
+
/**
* @param array $rawResponse Raw prediction array.
* @throws MindeeApiException Throws if a date is faulty.
@@ -58,7 +59,10 @@ public function __construct(array $rawResponse)
}
$this->id = $rawResponse['id'];
$this->status = $rawResponse['status'];
- if (array_key_exists('available_at', $rawResponse) && $rawResponse['available_at'] !== null && strtotime($rawResponse['available_at'])) {
+ if (
+ array_key_exists('available_at', $rawResponse) &&
+ $rawResponse['available_at'] !== null && strtotime($rawResponse['available_at'])
+ ) {
try {
$this->availableAt = new DateTimeImmutable($rawResponse['available_at']);
} catch (\Exception $e) {
diff --git a/tests/ClientUtilityMixinTest.php b/tests/ClientUtilityMixinTest.php
new file mode 100644
index 00000000..2694b63f
--- /dev/null
+++ b/tests/ClientUtilityMixinTest.php
@@ -0,0 +1,59 @@
+customSleep(1);
+ $elapsed = microtime(true) - $start;
+ $this->assertGreaterThanOrEqual($lowerBound, $elapsed);
+ $this->assertLessThanOrEqual($upperBound, $elapsed);
+ }
+
+ public function testCustomSleep2Seconds(): void {
+ $lowerBound = 2;
+ $upperBound = 2.1;
+
+ $start = microtime(true);
+ $this->customSleep(2);
+ $elapsed = microtime(true) - $start;
+ $this->assertGreaterThanOrEqual($lowerBound, $elapsed);
+ $this->assertLessThanOrEqual($upperBound, $elapsed);
+ }
+
+ public function testCustomSleep1dot5Seconds(): void {
+ $lowerBound = 1.5;
+ $upperBound = 1.6;
+
+ $start = microtime(true);
+ $this->customSleep(1.5);
+ $elapsed = microtime(true) - $start;
+ $this->assertGreaterThanOrEqual($lowerBound, $elapsed);
+ $this->assertLessThanOrEqual($upperBound, $elapsed);
+ }
+
+ public function testCustomSleep0Seconds(): void {
+ $start = microtime(true);
+ $this->customSleep(0);
+ $elapsed = microtime(true) - $start;
+ $this->assertLessThanOrEqual(0.0001, $elapsed);
+ }
+
+ public function testCustomSleepMinus1Seconds(): void {
+ $start = microtime(true);
+ $this->customSleep(-1);
+ $elapsed = microtime(true) - $start;
+ $this->assertLessThanOrEqual(0.0001, $elapsed);
+ }
+}
From e8058ddf62b671c94889ab00d8affa03fdfcd1ea Mon Sep 17 00:00:00 2001
From: sebastianMindee <130448732+sebastianMindee@users.noreply.github.com>
Date: Mon, 10 Nov 2025 14:03:53 +0100
Subject: [PATCH 02/12] add sub-second test
---
tests/ClientUtilityMixinTest.php | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/tests/ClientUtilityMixinTest.php b/tests/ClientUtilityMixinTest.php
index 2694b63f..62c261b5 100644
--- a/tests/ClientUtilityMixinTest.php
+++ b/tests/ClientUtilityMixinTest.php
@@ -21,6 +21,17 @@ public function testCustomSleep1Second(): void {
$this->assertLessThanOrEqual($upperBound, $elapsed);
}
+ public function testCustomSleep0dot33Seconds(): void {
+ $lowerBound = 0.33;
+ $upperBound = 0.43;
+
+ $start = microtime(true);
+ $this->customSleep(0.33);
+ $elapsed = microtime(true) - $start;
+ $this->assertGreaterThanOrEqual($lowerBound, $elapsed);
+ $this->assertLessThanOrEqual($upperBound, $elapsed);
+ }
+
public function testCustomSleep2Seconds(): void {
$lowerBound = 2;
$upperBound = 2.1;
From 47a532c5fc67bd01cc5a5afbaa277d822f0d950f Mon Sep 17 00:00:00 2001
From: sebastianMindee <130448732+sebastianMindee@users.noreply.github.com>
Date: Mon, 10 Nov 2025 14:08:56 +0100
Subject: [PATCH 03/12] fix test & rename mixin
---
src/Client.php | 2 +-
src/ClientV2.php | 2 +-
src/{ClientUtilityMixin.php => CustomSleepMixin.php} | 2 +-
.../{ClientUtilityMixinTest.php => CustomSleepMixinTest.php} | 4 ++--
tests/Input/URLInputSourceTestFunctional.php | 2 +-
5 files changed, 6 insertions(+), 6 deletions(-)
rename src/{ClientUtilityMixin.php => CustomSleepMixin.php} (95%)
rename tests/{ClientUtilityMixinTest.php => CustomSleepMixinTest.php} (96%)
diff --git a/src/Client.php b/src/Client.php
index 3e652720..05ea05e1 100644
--- a/src/Client.php
+++ b/src/Client.php
@@ -43,7 +43,7 @@
*/
class Client
{
- use ClientUtilityMixin;
+ use CustomSleepMixin;
/**
* Default owner for API products.
diff --git a/src/ClientV2.php b/src/ClientV2.php
index b74fd081..651f7ee1 100644
--- a/src/ClientV2.php
+++ b/src/ClientV2.php
@@ -14,7 +14,7 @@
*/
class ClientV2
{
- use ClientUtilityMixin;
+ use CustomSleepMixin;
/**
* @var MindeeApiV2 Mindee API V2.
diff --git a/src/ClientUtilityMixin.php b/src/CustomSleepMixin.php
similarity index 95%
rename from src/ClientUtilityMixin.php
rename to src/CustomSleepMixin.php
index 6a89db19..0128ea04 100644
--- a/src/ClientUtilityMixin.php
+++ b/src/CustomSleepMixin.php
@@ -2,7 +2,7 @@
namespace Mindee;
-trait ClientUtilityMixin
+trait CustomSleepMixin
{
/**
* Waits for a custom amount of time from either a float or an integer.
diff --git a/tests/ClientUtilityMixinTest.php b/tests/CustomSleepMixinTest.php
similarity index 96%
rename from tests/ClientUtilityMixinTest.php
rename to tests/CustomSleepMixinTest.php
index 62c261b5..5e8cc0cf 100644
--- a/tests/ClientUtilityMixinTest.php
+++ b/tests/CustomSleepMixinTest.php
@@ -6,9 +6,9 @@
* Custom delay tests.
* Note: Timers are purposefully kept loose due to frequent CI issues.
*/
-class ClientUtilityMixinTest extends TestCase
+class CustomSleepMixinTest extends TestCase
{
- use Mindee\ClientUtilityMixin;
+ use Mindee\CustomSleepMixin;
public function testCustomSleep1Second(): void {
$lowerBound = 1;
diff --git a/tests/Input/URLInputSourceTestFunctional.php b/tests/Input/URLInputSourceTestFunctional.php
index e18f0c8c..37524f20 100644
--- a/tests/Input/URLInputSourceTestFunctional.php
+++ b/tests/Input/URLInputSourceTestFunctional.php
@@ -18,7 +18,7 @@ protected function setUp(): void
$this->client = new Client();
$this->outputFilePath = (getenv('GITHUB_WORKSPACE') ?: ".") .
"/tests/resources/output/";
- $this->referenceFilePath = "https://github.com/mindee/client-lib-test-data/blob/main/products/invoice_splitter/invoice_5p.pdf?raw=true";
+ $this->referenceFilePath = "https://github.com/mindee/client-lib-test-data/blob/main/v1/products/invoice_splitter/invoice_5p.pdf?raw=true";
}
public static function tearDownAfterClass(): void
From 17d0cce5de97259fe02e76f91628acd2dfadb52e Mon Sep 17 00:00:00 2001
From: sebastianMindee <130448732+sebastianMindee@users.noreply.github.com>
Date: Mon, 10 Nov 2025 14:16:36 +0100
Subject: [PATCH 04/12] fix typo
---
src/CustomSleepMixin.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/CustomSleepMixin.php b/src/CustomSleepMixin.php
index 0128ea04..a157e6cc 100644
--- a/src/CustomSleepMixin.php
+++ b/src/CustomSleepMixin.php
@@ -18,7 +18,7 @@ protected static function customSleep(float|int $delay): void
$seconds = intval($delay);
$micros = $delay - $seconds;
if ($seconds > 0) {
- sleep($delay);
+ sleep($seconds);
}
if ($micros > 0) {
usleep($micros * 1_000_000);
From ab7adb8a62e07b85b7c55bef9993a62faab402a4 Mon Sep 17 00:00:00 2001
From: sebastianMindee <130448732+sebastianMindee@users.noreply.github.com>
Date: Mon, 10 Nov 2025 14:29:17 +0100
Subject: [PATCH 05/12] switch to stricter conversion for microseconds
---
src/CustomSleepMixin.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/CustomSleepMixin.php b/src/CustomSleepMixin.php
index a157e6cc..eec88256 100644
--- a/src/CustomSleepMixin.php
+++ b/src/CustomSleepMixin.php
@@ -16,7 +16,7 @@ protected static function customSleep(float|int $delay): void
}
$seconds = intval($delay);
- $micros = $delay - $seconds;
+ $micros = (int) round(((float) $delay - $seconds) * 1_000_000);
if ($seconds > 0) {
sleep($seconds);
}
From 3c0e7e9b3c3d4302169b713f3bafa1345424e6af Mon Sep 17 00:00:00 2001
From: sebastianMindee <130448732+sebastianMindee@users.noreply.github.com>
Date: Mon, 10 Nov 2025 15:07:32 +0100
Subject: [PATCH 06/12] fix wrong computation
---
src/CustomSleepMixin.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/CustomSleepMixin.php b/src/CustomSleepMixin.php
index eec88256..9ade2493 100644
--- a/src/CustomSleepMixin.php
+++ b/src/CustomSleepMixin.php
@@ -16,12 +16,12 @@ protected static function customSleep(float|int $delay): void
}
$seconds = intval($delay);
- $micros = (int) round(((float) $delay - $seconds) * 1_000_000);
+ $micros = (int) round(($delay - (float) $seconds) * 1_000_000);
if ($seconds > 0) {
sleep($seconds);
}
if ($micros > 0) {
- usleep($micros * 1_000_000);
+ usleep($micros);
}
}
}
From cfc427ff04b77af43e0b1e885dfc853d9395e5bd Mon Sep 17 00:00:00 2001
From: sebastianMindee <130448732+sebastianMindee@users.noreply.github.com>
Date: Mon, 10 Nov 2025 15:15:04 +0100
Subject: [PATCH 07/12] switch to time_nanosleep
---
src/CustomSleepMixin.php | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/src/CustomSleepMixin.php b/src/CustomSleepMixin.php
index 9ade2493..f723dffb 100644
--- a/src/CustomSleepMixin.php
+++ b/src/CustomSleepMixin.php
@@ -16,12 +16,7 @@ protected static function customSleep(float|int $delay): void
}
$seconds = intval($delay);
- $micros = (int) round(($delay - (float) $seconds) * 1_000_000);
- if ($seconds > 0) {
- sleep($seconds);
- }
- if ($micros > 0) {
- usleep($micros);
- }
+ $nanoseconds = abs((float) $seconds - $delay);
+ time_nanosleep($seconds, $nanoseconds * 1_000_000_000);
}
}
From c8400e30db17e3c6ee34022130b0f70f6c1782c6 Mon Sep 17 00:00:00 2001
From: sebastianMindee <130448732+sebastianMindee@users.noreply.github.com>
Date: Mon, 10 Nov 2025 15:51:58 +0100
Subject: [PATCH 08/12] fix windows test
---
src/CustomSleepMixin.php | 2 +-
tests/CustomSleepMixinTest.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/CustomSleepMixin.php b/src/CustomSleepMixin.php
index f723dffb..c458012e 100644
--- a/src/CustomSleepMixin.php
+++ b/src/CustomSleepMixin.php
@@ -16,7 +16,7 @@ protected static function customSleep(float|int $delay): void
}
$seconds = intval($delay);
- $nanoseconds = abs((float) $seconds - $delay);
+ $nanoseconds = (int) abs((float) $seconds - $delay);
time_nanosleep($seconds, $nanoseconds * 1_000_000_000);
}
}
diff --git a/tests/CustomSleepMixinTest.php b/tests/CustomSleepMixinTest.php
index 5e8cc0cf..e63fed13 100644
--- a/tests/CustomSleepMixinTest.php
+++ b/tests/CustomSleepMixinTest.php
@@ -22,7 +22,7 @@ public function testCustomSleep1Second(): void {
}
public function testCustomSleep0dot33Seconds(): void {
- $lowerBound = 0.33;
+ $lowerBound = 0.32; // Note: Windows struggles to run this one consistently when < 1 second
$upperBound = 0.43;
$start = microtime(true);
From e60363ff780a5d259abd5ac9cc0b8791fdc80bf4 Mon Sep 17 00:00:00 2001
From: sebastianMindee <130448732+sebastianMindee@users.noreply.github.com>
Date: Mon, 10 Nov 2025 15:57:48 +0100
Subject: [PATCH 09/12] fix typing
---
src/CustomSleepMixin.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/CustomSleepMixin.php b/src/CustomSleepMixin.php
index c458012e..7ddbeaa1 100644
--- a/src/CustomSleepMixin.php
+++ b/src/CustomSleepMixin.php
@@ -16,7 +16,7 @@ protected static function customSleep(float|int $delay): void
}
$seconds = intval($delay);
- $nanoseconds = (int) abs((float) $seconds - $delay);
- time_nanosleep($seconds, $nanoseconds * 1_000_000_000);
+ $nanoseconds = abs($seconds - (float) $delay);
+ time_nanosleep($seconds, (int) ($nanoseconds * 1_000_000_000));
}
}
From 2991c994ae1652bc7ae327b37df20b82e51a8532 Mon Sep 17 00:00:00 2001
From: sebastianMindee <130448732+sebastianMindee@users.noreply.github.com>
Date: Mon, 10 Nov 2025 16:08:37 +0100
Subject: [PATCH 10/12] fix windows-related timing issues
---
src/CustomSleepMixin.php | 6 ++++++
tests/CustomSleepMixinTest.php | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/CustomSleepMixin.php b/src/CustomSleepMixin.php
index 7ddbeaa1..27f5199e 100644
--- a/src/CustomSleepMixin.php
+++ b/src/CustomSleepMixin.php
@@ -17,6 +17,12 @@ protected static function customSleep(float|int $delay): void
$seconds = intval($delay);
$nanoseconds = abs($seconds - (float) $delay);
+ if (
+ strtoupper(substr(PHP_OS_FAMILY, 0, 7)) === 'WINDOWS' &&
+ $nanoseconds > 0.000000001
+ ) {
+ usleep(100000);
+ }
time_nanosleep($seconds, (int) ($nanoseconds * 1_000_000_000));
}
}
diff --git a/tests/CustomSleepMixinTest.php b/tests/CustomSleepMixinTest.php
index e63fed13..5e8cc0cf 100644
--- a/tests/CustomSleepMixinTest.php
+++ b/tests/CustomSleepMixinTest.php
@@ -22,7 +22,7 @@ public function testCustomSleep1Second(): void {
}
public function testCustomSleep0dot33Seconds(): void {
- $lowerBound = 0.32; // Note: Windows struggles to run this one consistently when < 1 second
+ $lowerBound = 0.33;
$upperBound = 0.43;
$start = microtime(true);
From 4fb3037a7e2fc684b7720a936da295df9f429188 Mon Sep 17 00:00:00 2001
From: sebastianMindee <130448732+sebastianMindee@users.noreply.github.com>
Date: Mon, 10 Nov 2025 16:12:37 +0100
Subject: [PATCH 11/12] fix windows-related timing issues... again
---
src/CustomSleepMixin.php | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/CustomSleepMixin.php b/src/CustomSleepMixin.php
index 27f5199e..c152e120 100644
--- a/src/CustomSleepMixin.php
+++ b/src/CustomSleepMixin.php
@@ -18,10 +18,9 @@ protected static function customSleep(float|int $delay): void
$seconds = intval($delay);
$nanoseconds = abs($seconds - (float) $delay);
if (
- strtoupper(substr(PHP_OS_FAMILY, 0, 7)) === 'WINDOWS' &&
- $nanoseconds > 0.000000001
+ strtoupper(substr(PHP_OS_FAMILY, 0, 7)) === 'WINDOWS'
) {
- usleep(100000);
+ usleep(100_000);
}
time_nanosleep($seconds, (int) ($nanoseconds * 1_000_000_000));
}
From ec7ee961356e9cde1dc9d4516645f94702ee12cc Mon Sep 17 00:00:00 2001
From: sebastianMindee <130448732+sebastianMindee@users.noreply.github.com>
Date: Mon, 10 Nov 2025 16:16:09 +0100
Subject: [PATCH 12/12] reduce windows fix delay timer
---
src/CustomSleepMixin.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/CustomSleepMixin.php b/src/CustomSleepMixin.php
index c152e120..9c7cd0cd 100644
--- a/src/CustomSleepMixin.php
+++ b/src/CustomSleepMixin.php
@@ -20,7 +20,7 @@ protected static function customSleep(float|int $delay): void
if (
strtoupper(substr(PHP_OS_FAMILY, 0, 7)) === 'WINDOWS'
) {
- usleep(100_000);
+ usleep(1000);
}
time_nanosleep($seconds, (int) ($nanoseconds * 1_000_000_000));
}