1212use Psr \SimpleCache \CacheInterface ;
1313use ReflectionClass ;
1414use ReflectionMethod ;
15+ use Symfony \Component \Lock \Factory as LockFactory ;
16+ use Symfony \Component \Lock \Store \SemaphoreStore ;
1517use TheCodingMachine \ClassExplorer \Glob \GlobClassExplorer ;
1618use TheCodingMachine \GraphQLite \AnnotationReader ;
1719use TheCodingMachine \GraphQLite \Annotations \ExtendType ;
@@ -119,6 +121,10 @@ final class GlobTypeMapper implements TypeMapperInterface
119121 * @var bool
120122 */
121123 private $ recursive ;
124+ /**
125+ * @var LockFactory
126+ */
127+ private $ lockFactory ;
122128
123129 /**
124130 * @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
136142 $ this ->inputTypeGenerator = $ inputTypeGenerator ;
137143 $ this ->inputTypeUtils = $ inputTypeUtils ;
138144 $ this ->recursive = $ recursive ;
145+ $ store = new SemaphoreStore ();
146+ $ this ->lockFactory = new LockFactory ($ store );
139147 }
140148
141149 /**
@@ -160,7 +168,7 @@ private function getMaps(): array
160168 $ this ->mapClassToFactory === null ||
161169 $ this ->mapInputNameToFactory
162170 ) {
163- $ this ->buildMap ();
171+ $ this ->lockAndBuildMap ();
164172 // This is a very short lived cache. Useful to avoid overloading a server in case of heavy load.
165173 // Defaults to 2 seconds.
166174 $ this ->cache ->set ($ keyClassCache , $ this ->mapClassToTypeArray , $ this ->globTtl );
@@ -258,6 +266,17 @@ private function getClassList(): array
258266 return $ this ->classes ;
259267 }
260268
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+
261280 private function buildMap (): void
262281 {
263282 $ this ->mapClassToTypeArray = [];
@@ -303,27 +322,39 @@ private function buildMap(): void
303322
304323 private function buildMapClassToExtendTypeArray (): void
305324 {
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 );
310332
311- if ($ extendType !== null ) {
312- $ this ->storeExtendTypeMapperByClassInCache ($ className , $ extendType , $ refClass ->getFileName ());
333+ if ($ extendType !== null ) {
334+ $ this ->storeExtendTypeMapperByClassInCache ($ className , $ extendType , $ refClass ->getFileName ());
335+ }
313336 }
337+ } finally {
338+ $ lock ->release ();
314339 }
315340 }
316341
317342 private function buildMapNameToExtendTypeArray (RecursiveTypeMapperInterface $ recursiveTypeMapper ): void
318343 {
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 );
323351
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+ }
326355 }
356+ } finally {
357+ $ lock ->release ();
327358 }
328359 }
329360
0 commit comments