Skip to content

Locks are placed before cache check #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions src/GlobControllerQueryProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Mouf\Composer\ClassNameMapper;
use Psr\Container\ContainerInterface;
use Psr\SimpleCache\CacheInterface;
use Symfony\Component\Lock\Store\SemaphoreStore;
use Symfony\Component\Lock\Lock;
use TheCodingMachine\ClassExplorer\Glob\GlobClassExplorer;
use TheCodingMachine\GraphQLite\Mappers\RecursiveTypeMapperInterface;
use Symfony\Component\Lock\Factory as LockFactory;
Expand Down Expand Up @@ -100,16 +100,24 @@ private function getInstancesList(): array
$key = 'globQueryProvider_'.str_replace('\\', '_', $this->namespace);
$this->instancesList = $this->cache->get($key);
if ($this->instancesList === null) {
$this->instancesList = $this->lockAndBuildInstanceList();
$lock = $this->lockFactory->createLock('buildInstanceList_'.$this->namespace, 5);
if ($lock->isAcquired()) {
// Lock is being held right now. Generation is happening.
// Let's wait and fetch the result from the cache.
$lock->acquire(true);
$lock->release();
return $this->getInstancesList();
}

$this->instancesList = $this->lockAndBuildInstanceList($lock);
$this->cache->set($key, $this->instancesList, $this->cacheTtl);
}
}
return $this->instancesList;
}

private function lockAndBuildInstanceList(): array
private function lockAndBuildInstanceList(Lock $lock): array
{
$lock = $this->lockFactory->createLock('buildInstanceList_'.$this->namespace, 5);
$lock->acquire(true);
try {
return $this->buildInstancesList();
Expand Down
42 changes: 33 additions & 9 deletions src/Mappers/GlobTypeMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use ReflectionClass;
use ReflectionMethod;
use Symfony\Component\Lock\Factory as LockFactory;
use Symfony\Component\Lock\Lock;
use Symfony\Component\Lock\Store\SemaphoreStore;
use TheCodingMachine\ClassExplorer\Glob\GlobClassExplorer;
use TheCodingMachine\GraphQLite\AnnotationReader;
Expand Down Expand Up @@ -167,7 +168,15 @@ private function getMaps(): array
$this->mapClassToFactory === null ||
$this->mapInputNameToFactory
) {
$this->lockAndBuildMap();
$lock = $this->lockFactory->createLock('buildmap_'.$this->namespace, 5);
if ($lock->isAcquired()) {
// Lock is being held right now. Generation is happening.
// Let's wait and fetch the result from the cache.
$lock->acquire(true);
$lock->release();
return $this->getMaps();
}
$this->lockAndBuildMap($lock);
// This is a very short lived cache. Useful to avoid overloading a server in case of heavy load.
// Defaults to 2 seconds.
$this->cache->set($keyClassCache, $this->mapClassToTypeArray, $this->globTtl);
Expand Down Expand Up @@ -212,7 +221,16 @@ private function getMapClassToExtendTypeArray(): array
$keyExtendClassCache = 'globTypeMapperExtend_'.$namespace;
$this->mapClassToExtendTypeArray = $this->cache->get($keyExtendClassCache);
if ($this->mapClassToExtendTypeArray === null) {
$this->buildMapClassToExtendTypeArray();
$lock = $this->lockFactory->createLock('buildmapclassextend_'.$this->namespace, 5);
if ($lock->isAcquired()) {
// Lock is being held right now. Generation is happening.
// Let's wait and fetch the result from the cache.
$lock->acquire(true);
$lock->release();
return $this->getMapClassToExtendTypeArray();
}

$this->buildMapClassToExtendTypeArray($lock);
// This is a very short lived cache. Useful to avoid overloading a server in case of heavy load.
// Defaults to 2 seconds.
$this->cache->set($keyExtendClassCache, $this->mapClassToExtendTypeArray, $this->globTtl);
Expand All @@ -229,7 +247,16 @@ private function getMapNameToExtendType(RecursiveTypeMapperInterface $recursiveT
$keyExtendNameCache = 'globTypeMapperExtend_names_'.$namespace;
$this->mapNameToExtendType = $this->cache->get($keyExtendNameCache);
if ($this->mapNameToExtendType === null) {
$this->buildMapNameToExtendTypeArray($recursiveTypeMapper);
$lock = $this->lockFactory->createLock('buildmapnameextend_'.$this->namespace, 5);
if ($lock->isAcquired()) {
// Lock is being held right now. Generation is happening.
// Let's wait and fetch the result from the cache.
$lock->acquire(true);
$lock->release();
return $this->getMapNameToExtendType($recursiveTypeMapper);
}

$this->buildMapNameToExtendTypeArray($lock, $recursiveTypeMapper);
// This is a very short lived cache. Useful to avoid overloading a server in case of heavy load.
// Defaults to 2 seconds.
$this->cache->set($keyExtendNameCache, $this->mapNameToExtendType, $this->globTtl);
Expand Down Expand Up @@ -265,9 +292,8 @@ private function getClassList(): array
return $this->classes;
}

private function lockAndBuildMap(): void
private function lockAndBuildMap(Lock $lock): void
{
$lock = $this->lockFactory->createLock('buildmap_'.$this->namespace, 5);
$lock->acquire(true);
try {
$this->buildMap();
Expand Down Expand Up @@ -319,9 +345,8 @@ private function buildMap(): void
}
}

private function buildMapClassToExtendTypeArray(): void
private function buildMapClassToExtendTypeArray(Lock $lock): void
{
$lock = $this->lockFactory->createLock('buildmapclassextend_'.$this->namespace, 5);
$lock->acquire(true);
try {
$this->mapClassToExtendTypeArray = [];
Expand All @@ -338,9 +363,8 @@ private function buildMapClassToExtendTypeArray(): void
}
}

private function buildMapNameToExtendTypeArray(RecursiveTypeMapperInterface $recursiveTypeMapper): void
private function buildMapNameToExtendTypeArray(Lock $lock, RecursiveTypeMapperInterface $recursiveTypeMapper): void
{
$lock = $this->lockFactory->createLock('buildmapnameextend_'.$this->namespace, 5);
$lock->acquire(true);
try {
$this->mapNameToExtendType = [];
Expand Down