|
7 | 7 | use Magento\Catalog\Model\Product;
|
8 | 8 | use OpenAI\Factory;
|
9 | 9 | use OpenAI\Client;
|
| 10 | +use OpenAI\Responses\Meta; |
| 11 | +use OpenAI\Exceptions\ErrorException; |
10 | 12 |
|
11 | 13 | class Enricher
|
12 | 14 | {
|
@@ -73,13 +75,43 @@ public function enrichAttribute($product, $attributeCode)
|
73 | 75 | if($result = $response->choices[0]) {
|
74 | 76 | $product->setData($attributeCode, $result->message?->content);
|
75 | 77 | }
|
| 78 | + $this->backoff($response->meta()); |
76 | 79 | }
|
77 | 80 | }
|
78 | 81 |
|
| 82 | + public function backoff(Meta $meta) |
| 83 | + { |
| 84 | + if($meta->requestLimit->remaining < 1) { |
| 85 | + sleep($this->strToSeconds($meta->requestLimit->reset)); |
| 86 | + } |
| 87 | + // 1 token ~= 0.75 word |
| 88 | + // do not use config value |
| 89 | + if($meta->tokenLimit->remaining < 1000) { |
| 90 | + sleep($this->strToSeconds($meta->tokenLimit->reset)); |
| 91 | + } |
| 92 | + } |
| 93 | + |
| 94 | + private function strToSeconds(string $time) |
| 95 | + { |
| 96 | + preg_match('/(?:([0-9]+)h)?(?:([0-9]+)m)?(?:([0-9]+)s)?/', $time, $matches); |
| 97 | + |
| 98 | + $hours = isset($matches[1]) ? intval($matches[1]) : 0; |
| 99 | + $minutes = isset($matches[2]) ? intval($matches[2]) : 0; |
| 100 | + $seconds = isset($matches[3]) ? intval($matches[3]) : 0; |
| 101 | + |
| 102 | + return $hours * 3600 + $minutes * 60 + $seconds; |
| 103 | + } |
| 104 | + |
79 | 105 | public function execute(Product $product)
|
80 | 106 | {
|
81 | 107 | foreach ($this->getAttributes() as $attributeCode) {
|
82 |
| - $this->enrichAttribute($product, $attributeCode); |
| 108 | + try { |
| 109 | + $this->enrichAttribute($product, $attributeCode); |
| 110 | + } catch (ErrorException $e) { |
| 111 | + // try it one more time just in case we failed to catch the limit in backoff |
| 112 | + sleep(60); |
| 113 | + $this->enrichAttribute($product, $attributeCode); |
| 114 | + } |
83 | 115 | }
|
84 | 116 | //@TODO: throw exception?
|
85 | 117 | }
|
|
0 commit comments