4
4
5
5
namespace Elegantly \Translator \Services \Translate ;
6
6
7
+ use Closure ;
7
8
use InvalidArgumentException ;
8
9
use OpenAI ;
9
10
@@ -32,7 +33,7 @@ public static function makeClient(): \OpenAI\Client
32
33
$ apiKey = config ('translator.translate.services.openai.key ' ) ?? config ('translator.services.openai.key ' );
33
34
$ organization = config ('translator.translate.services.openai.organization ' ) ?? config ('translator.services.openai.organization ' );
34
35
$ project = config ('translator.translate.services.openai.project ' ) ?? config ('translator.services.openai.project ' );
35
- $ timeout = config ( ' translator.translate.services.openai.request_timeout ' ) ?? config ( ' translator.services.openai.request_timeout ' ) ?? 120 ;
36
+ $ timeout = static :: getTimeout () ;
36
37
37
38
if (blank ($ apiKey )) {
38
39
throw new InvalidArgumentException (
@@ -50,32 +51,64 @@ public static function makeClient(): \OpenAI\Client
50
51
->make ();
51
52
}
52
53
54
+ public static function getTimeout (): int
55
+ {
56
+ return (int ) (config ('translator.translate.services.openai.request_timeout ' ) ?? config ('translator.services.openai.request_timeout ' ) ?? 120 );
57
+ }
58
+
59
+ /**
60
+ * @template TValue
61
+ *
62
+ * @param (Closure():TValue) $callback
63
+ * @return TValue
64
+ */
65
+ protected function withTemporaryTimeout (int $ limit , Closure $ callback ): mixed
66
+ {
67
+ $ initial = (int ) ini_get ('max_execution_time ' );
68
+
69
+ set_time_limit ($ limit );
70
+
71
+ try {
72
+ return $ callback ();
73
+ } catch (\Throwable $ th ) {
74
+ throw $ th ;
75
+ } finally {
76
+ set_time_limit ($ initial );
77
+ }
78
+ }
79
+
53
80
public function translateAll (array $ texts , string $ targetLocale ): array
54
81
{
55
- return collect ($ texts )
56
- ->chunk (20 )
57
- ->map (function ($ chunk ) use ($ targetLocale ) {
58
- $ response = $ this ->client ->chat ()->create ([
59
- 'model ' => $ this ->model ,
60
- 'response_format ' => ['type ' => 'json_object ' ],
61
- 'messages ' => [
62
- [
63
- 'role ' => 'system ' ,
64
- 'content ' => str_replace ('{targetLocale} ' , $ targetLocale , $ this ->prompt ),
65
- ],
66
- [
67
- 'role ' => 'user ' ,
68
- 'content ' => $ chunk ->toJson (),
69
- ],
70
- ],
71
- ]);
72
-
73
- $ content = $ response ->choices [0 ]->message ->content ;
74
- $ translations = json_decode ($ content , true );
75
-
76
- return $ translations ;
77
- })
78
- ->collapse ()
79
- ->toArray ();
82
+ return $ this ->withTemporaryTimeout (
83
+ static ::getTimeout (),
84
+ function () use ($ texts , $ targetLocale ) {
85
+ return collect ($ texts )
86
+ ->chunk (50 )
87
+ ->map (function ($ chunk ) use ($ targetLocale ) {
88
+ $ response = $ this ->client ->chat ()->create ([
89
+ 'model ' => $ this ->model ,
90
+ 'response_format ' => ['type ' => 'json_object ' ],
91
+ 'messages ' => [
92
+ [
93
+ 'role ' => 'system ' ,
94
+ 'content ' => str_replace ('{targetLocale} ' , $ targetLocale , $ this ->prompt ),
95
+ ],
96
+ [
97
+ 'role ' => 'user ' ,
98
+ 'content ' => $ chunk ->toJson (),
99
+ ],
100
+ ],
101
+ ]);
102
+
103
+ $ content = $ response ->choices [0 ]->message ->content ;
104
+ $ translations = json_decode ($ content , true );
105
+
106
+ return $ translations ;
107
+ })
108
+ ->collapse ()
109
+ ->toArray ();
110
+ }
111
+ );
112
+
80
113
}
81
114
}
0 commit comments