12
12
use Psr \SimpleCache \CacheInterface ;
13
13
use ReflectionClass ;
14
14
use ReflectionMethod ;
15
+ use Symfony \Component \Lock \Factory as LockFactory ;
16
+ use Symfony \Component \Lock \Store \SemaphoreStore ;
15
17
use TheCodingMachine \ClassExplorer \Glob \GlobClassExplorer ;
16
18
use TheCodingMachine \GraphQLite \AnnotationReader ;
17
19
use TheCodingMachine \GraphQLite \Annotations \ExtendType ;
@@ -119,6 +121,10 @@ final class GlobTypeMapper implements TypeMapperInterface
119
121
* @var bool
120
122
*/
121
123
private $ recursive ;
124
+ /**
125
+ * @var LockFactory
126
+ */
127
+ private $ lockFactory ;
122
128
123
129
/**
124
130
* @param string $namespace The namespace that contains the GraphQL types (they must have a `@Type` annotation)
@@ -136,6 +142,8 @@ public function __construct(string $namespace, TypeGenerator $typeGenerator, Inp
136
142
$ this ->inputTypeGenerator = $ inputTypeGenerator ;
137
143
$ this ->inputTypeUtils = $ inputTypeUtils ;
138
144
$ this ->recursive = $ recursive ;
145
+ $ store = new SemaphoreStore ();
146
+ $ this ->lockFactory = new LockFactory ($ store );
139
147
}
140
148
141
149
/**
@@ -160,7 +168,7 @@ private function getMaps(): array
160
168
$ this ->mapClassToFactory === null ||
161
169
$ this ->mapInputNameToFactory
162
170
) {
163
- $ this ->buildMap ();
171
+ $ this ->lockAndBuildMap ();
164
172
// This is a very short lived cache. Useful to avoid overloading a server in case of heavy load.
165
173
// Defaults to 2 seconds.
166
174
$ this ->cache ->set ($ keyClassCache , $ this ->mapClassToTypeArray , $ this ->globTtl );
@@ -258,6 +266,17 @@ private function getClassList(): array
258
266
return $ this ->classes ;
259
267
}
260
268
269
+ private function lockAndBuildMap (): void
270
+ {
271
+ $ lock = $ this ->lockFactory ->createLock ('buildmap_ ' .$ this ->namespace , 5 );
272
+ $ lock ->acquire (true );
273
+ try {
274
+ $ this ->buildMap ();
275
+ } finally {
276
+ $ lock ->release ();
277
+ }
278
+ }
279
+
261
280
private function buildMap (): void
262
281
{
263
282
$ this ->mapClassToTypeArray = [];
@@ -303,27 +322,39 @@ private function buildMap(): void
303
322
304
323
private function buildMapClassToExtendTypeArray (): void
305
324
{
306
- $ this ->mapClassToExtendTypeArray = [];
307
- $ classes = $ this ->getClassList ();
308
- foreach ($ classes as $ className => $ refClass ) {
309
- $ extendType = $ this ->annotationReader ->getExtendTypeAnnotation ($ refClass );
325
+ $ lock = $ this ->lockFactory ->createLock ('buildmapclassextend_ ' .$ this ->namespace , 5 );
326
+ $ lock ->acquire (true );
327
+ try {
328
+ $ this ->mapClassToExtendTypeArray = [];
329
+ $ classes = $ this ->getClassList ();
330
+ foreach ($ classes as $ className => $ refClass ) {
331
+ $ extendType = $ this ->annotationReader ->getExtendTypeAnnotation ($ refClass );
310
332
311
- if ($ extendType !== null ) {
312
- $ this ->storeExtendTypeMapperByClassInCache ($ className , $ extendType , $ refClass ->getFileName ());
333
+ if ($ extendType !== null ) {
334
+ $ this ->storeExtendTypeMapperByClassInCache ($ className , $ extendType , $ refClass ->getFileName ());
335
+ }
313
336
}
337
+ } finally {
338
+ $ lock ->release ();
314
339
}
315
340
}
316
341
317
342
private function buildMapNameToExtendTypeArray (RecursiveTypeMapperInterface $ recursiveTypeMapper ): void
318
343
{
319
- $ this ->mapNameToExtendType = [];
320
- $ classes = $ this ->getClassList ();
321
- foreach ($ classes as $ className => $ refClass ) {
322
- $ extendType = $ this ->annotationReader ->getExtendTypeAnnotation ($ refClass );
344
+ $ lock = $ this ->lockFactory ->createLock ('buildmapnameextend_ ' .$ this ->namespace , 5 );
345
+ $ lock ->acquire (true );
346
+ try {
347
+ $ this ->mapNameToExtendType = [];
348
+ $ classes = $ this ->getClassList ();
349
+ foreach ($ classes as $ className => $ refClass ) {
350
+ $ extendType = $ this ->annotationReader ->getExtendTypeAnnotation ($ refClass );
323
351
324
- if ($ extendType !== null ) {
325
- $ this ->storeExtendTypeMapperByNameInCache ($ className , $ extendType , $ refClass ->getFileName (), $ recursiveTypeMapper );
352
+ if ($ extendType !== null ) {
353
+ $ this ->storeExtendTypeMapperByNameInCache ($ className , $ extendType , $ refClass ->getFileName (), $ recursiveTypeMapper );
354
+ }
326
355
}
356
+ } finally {
357
+ $ lock ->release ();
327
358
}
328
359
}
329
360
0 commit comments