8000 Merge branch '5.4' into 6.0 · symfony/symfony@eb749ec · GitHub
[go: up one dir, main page]

Skip to content

Commit eb749ec

Browse files
Merge branch '5.4' into 6.0
* 5.4: [5.4] cs fixes [5.3] cs fixes [Cache] Fix saving items with no expiration through ProxyAdapter CS fixes [HttpClient] Fix tracing requests made after calling withOptions() [Cache] disable lock on CLI Revert "feature #41989 [Cache] make `LockRegistry` use semaphores when possible (nicolas-grekas)" [HttpKernel] fix how configuring log-level and status-code by exception works [VarDumper] add more "transient-on-macos" groups
2 parents d737dab + 646c33f commit eb749ec

File tree

39 files changed

+182
-110
lines changed

39 files changed

+182
-110
lines changed

.php-cs-fixer.dist.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
'@Symfony' => true,
1212
'@Symfony:risky' => true,
1313
'protected_to_private' => false,
14+
'native_constant_invocation' => ['strict' => false],
1415
'nullable_type_declaration_for_default_null_value' => ['use_nullable_type_declaration' => false],
1516
])
1617
->setRiskyAllowed(true)

src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public function loadClassMetadata(ClassMetadata $metadata): bool
4949
$className = $metadata->getClassName();
5050
try {
5151
$doctrineMetadata = $this->entityManager->getClassMetadata($className);
52-
} catch (MappingException | OrmMappingException $exception) {
52+
} catch (MappingException|OrmMappingException $exception) {
5353
return false;
5454
}
5555

src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
class WorkflowDumpCommand extends Command
3737
{
3838
/**
39-
* string is the service id
39+
* string is the service id.
40+
*
4041
* @var array<string, Definition>
4142
*/
4243
private array $workflows = [];

src/Symfony/Component/Cache/Adapter/AbstractAdapter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ static function ($deferred, $namespace, &$expiredIds, $getId, $defaultLifetime)
7474
$key = (string) $key;
7575
if (null === $item->expiry) {
7676
$ttl = 0 < $defaultLifetime ? $defaultLifetime : 0;
77-
} elseif (0 === $item->expiry) {
77+
} elseif (!$item->expiry) {
7878
$ttl = 0;
7979
} elseif (0 >= $ttl = (int) (0.1 + $item->expiry - $now)) {
8080
$expiredIds[] = $getId($key);

src/Symfony/Component/Cache/Adapter/AbstractTagAwareAdapter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ static function ($deferred, &$expiredIds, $getId, $tagPrefix, $defaultLifetime)
7979
$key = (string) $key;
8080
if (null === $item->expiry) {
8181
$ttl = 0 < $defaultLifetime ? $defaultLifetime : 0;
82-
} elseif (0 === $item->expiry) {
82+
} elseif (!$item->expiry) {
8383
$ttl = 0;
8484
} elseif (0 >= $ttl = (int) (0.1 + $item->expiry - $now)) {
8585
$expiredIds[] = $getId($key);

src/Symfony/Component/Cache/Adapter/ArrayAdapter.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,14 @@ public function save(CacheItemInterface $item): bool
182182

183183
$now = microtime(true);
184184

185-
if (0 === $expiry) {
186-
$expiry = \PHP_INT_MAX;
187-
}
188-
189-
if (null !== $expiry && $expiry <= $now) {
190-
$this->deleteItem($key);
185+
if (null !== $expiry) {
186+
if (!$expiry) {
187+
$expiry = \PHP_INT_MAX;
188+
} elseif ($expiry <= $now) {
189+
$this->deleteItem($key);
191190

192-
return true;
191+
return true;
192+
}
193193
}
194194
if ($this->storeSerialized && null === $value = $this->freeze($value, $key)) {
195195
return false;

src/Symfony/Component/Cache/Adapter/ProxyAdapter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ static function (CacheItemInterface $innerItem, array $item) {
9292
$item["\0*\0value"] = ["\x9D".pack('VN', (int) (0.1 + $metadata[self::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET), $metadata[self::METADATA_CTIME])."\x5F" => $item["\0*\0value"]];
9393
}
9494
$innerItem->set($item["\0*\0value"]);
95-
$innerItem->expiresAt(null !== $item["\0*\0expiry"] ? \DateTime::createFromFormat('U.u', sprintf('%.6F', 0 === $item["\0*\0expiry"] ? \PHP_INT_MAX : $item["\0*\0expiry"])) : null);
95+
$innerItem->expiresAt(null !== $item["\0*\0expiry"] ? \DateTime::createFromFormat('U.u', sprintf('%.6F', $item["\0*\0expiry"])) : null);
9696
},
9797
null,
9898
CacheItem::class

src/Symfony/Component/Cache/CHANGELOG.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ CHANGELOG
1010
5.4
1111
---
1212

13-
* Make `LockRegistry` use semaphores when possible
1413
* Deprecate `DoctrineProvider` and `DoctrineAdapter` because these classes have been added to the `doctrine/cache` package
1514
* Add `DoctrineDbalAdapter` identical to `PdoAdapter` for `Doctrine\DBAL\Connection` or DBAL URL
1615
* Deprecate usage of `PdoAdapter` with `Doctrine\DBAL\Connection` or DBAL URL

src/Symfony/Component/Cache/LockRegistry.php

Lines changed: 11 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
final class LockRegistry
2828
{
2929
private static $openedFiles = [];
30-
private static $lockedKeys;
30+
private static $lockedFiles;
3131

3232
/**
3333
* The number of items in this list controls the max number of concurrent processes.
@@ -76,41 +76,33 @@ public static function setFiles(array $files): array
7676
fclose($file);
7777
}
7878
}
79-
self::$openedFiles = self::$lockedKeys = [];
79+
self::$openedFiles = self::$lockedFiles = [];
8080

8181
return $previousFiles;
8282
}
8383

8484
public static function compute(callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata = null, LoggerInterface $logger = null)
8585
{
86-
if ('\\' === \DIRECTORY_SEPARATOR && null === self::$lockedKeys) {
86+
if ('\\' === \DIRECTORY_SEPARATOR && null === self::$lockedFiles) {
8787
// disable locking on Windows by default
88-
self::$files = self::$lockedKeys = [];
88+
self::$files = self::$lockedFiles = [];
8989
}
9090

91-
$key = unpack('i', md5($item->getKey(), true))[1];
91+
$key = self::$files ? abs(crc32($item->getKey())) % \count(self::$files) : -1;
9292

93-
if (!\function_exists('sem_get')) {
94-
$key = self::$files ? abs($key) % \count(self::$files) : null;
95-
}
96-
97-
if (null === $key || (self::$lockedKeys[$key] ?? false) || !$lock = self::open($key)) {
93+
if ($key < 0 || (self::$lockedFiles[$key] ?? false) || !$lock = self::open($key)) {
9894
return $callback($item, $save);
9995
}
10096

10197
while (true) {
10298
try {
10399
$locked = false;
104100
// race to get the lock in non-blocking mode
105-
if ($wouldBlock = \function_exists('sem_get')) {
106-
$locked = @sem_acquire($lock, true);
107-
} else {
108-
$locked = flock($lock, \LOCK_EX | \LOCK_NB, $wouldBlock);
109-
}
101+
$locked = flock($lock, \LOCK_EX | \LOCK_NB, $wouldBlock);
110102

111103
if ($locked || !$wouldBlock) {
112104
$logger && $logger->info(sprintf('Lock %s, now computing item "{key}"', $locked ? 'acquired' : 'not supported'), ['key' => $item->getKey()]);
113-
self::$lockedKeys[$key] = true;
105+
self::$lockedFiles[$key] = true;
114106

115107
$value = $callback($item, $save);
116108

@@ -125,25 +117,12 @@ public static function compute(callable $callback, ItemInterface $item, bool &$s
125117

126118
return $value;
127119
}
128-
129120
// if we failed the race, retry locking in blocking mode to wait for the winner
130121
$logger && $logger->info('Item "{key}" is locked, waiting for it to be released', ['key' => $item->getKey()]);
131-
132-
if (\function_exists('sem_get')) {
133-
$lock = sem_get($key);
134-
@sem_acquire($lock);
135-
} else {
136-
flock($lock, \LOCK_SH);
137-
}
122+
flock($lock, \LOCK_SH);
138123
} finally {
139-
if ($locked) {
140-
if (\function_exists('sem_get')) {
141-
sem_remove($lock);
142-
} else {
143-
flock($lock, \LOCK_UN);
144-
}
145-
}
146-
unset(self::$lockedKeys[$key]);
124+
flock($lock, \LOCK_UN);
125+
unset(self::$lockedFiles[$key]);
147126
}
148127
static $signalingException, $signalingCallback;
149128
$signalingException = $signalingException ?? unserialize("O:9:\"Exception\":1:{s:16:\"\0Exception\0trace\";a:0:{}}");
@@ -168,10 +147,6 @@ public static function compute(callable $callback, ItemInterface $item, bool &$s
168147

169148
private static function open(int $key)
170149
{
171-
if (\function_exists('sem_get')) {
172-
return sem_get($key);
173-
}
174-
175150
if (null !== $h = self::$openedFiles[$key] ?? null) {
176151
return $h;
177152
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Cache\Tests\Adapter;
13+
14+
use Psr\Cache\CacheItemPoolInterface;
15+
use Symfony\Component\Cache\Adapter\AbstractAdapter;
16+
use Symfony\Component\Cache\Adapter\ProxyAdapter;
17+
use Symfony\Component\Cache\Adapter\RedisAdapter;
18+
use Symfony\Component\Cache\CacheItem;
19+
20+
/**
21+
* @group integration
22+
*/
23+
class ProxyAdapterAndRedisAdapterTest extends AbstractRedisAdapterTest
24+
{
25+
protected $skippedTests = [
26+
'testPrune' => 'RedisAdapter does not implement PruneableInterface.',
27+
];
28+
29+
public static function setUpBeforeClass(): void
30+
{
31+
parent::setUpBeforeClass();
32+
self::$redis = AbstractAdapter::createConnection('redis://'.getenv('REDIS_HOST'));
33+
}
34+
35+
public function createCachePool($defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface
36+
{
37+
return new ProxyAdapter(new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), 100), 'ProxyNS', $defaultLifetime);
38+
}
39+
40+
public function testSaveItemPermanently()
41+
{
42+
$setCacheItemExpiry = \Closure::bind(
43+
static function (CacheItem $item, $expiry) {
44+
$item->expiry = $expiry;
45+
46+
return $item;
47+
},
48+
null,
49+
CacheItem::class
50+
);
51+
52+
$cache = $this->createCachePool(1);
53+
$value = rand();
54+
$item = $cache->getItem('foo');
55+
$setCacheItemExpiry($item, 0);
56+
$cache->save($item->set($value));
57+
$item = $cache->getItem('bar');
58+
$setCacheItemExpiry($item, 0.0);
59+
$cache->save($item->set($value));
60+
$item = $cache->getItem('baz');
61+
$cache->save($item->set($value));
62+
63+
$this->assertSame($value, $this->cache->getItem('foo')->get());
64+
$this->assertSame($value, $this->cache->getItem('bar')->get());
65+
$this->assertSame($value, $this->cache->getItem('baz')- 10000 >get());
66+
67+
sleep(1);
68+
$this->assertSame($value, $this->cache->getItem('foo')->get());
69+
$this->assertSame($value, $this->cache->getItem('bar')->get());
70+
$this->assertFalse($this->cache->getItem('baz')->isHit());
71+
}
72+
}

src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@
1414
use PHPUnit\Framework\MockObject\MockObject;
1515
use Psr\Cache\CacheItemInterface;
1616
use Psr\Cache\CacheItemPoolInterface;
17-
use Psr\Log\LoggerInterface;
1817
use Symfony\Component\Cache\Adapter\AdapterInterface;
1918
use Symfony\Component\Cache\Adapter\ArrayAdapter;
2019
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
2120
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
22-
use Symfony\Component\Cache\LockRegistry;
2321
use Symfony\Component\Cache\Tests\Fixtures\PrunableAdapter;
2422
use Symfony\Component\Filesystem\Filesystem;
2523

@@ -181,24 +179,6 @@ public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemAndOnlyHasTags
181179
$this->assertFalse($item->isHit());
182180
}
183181

184-
public function testLog()
185-
{
186-
$lockFiles = LockRegistry::setFiles([__FILE__]);
187-
188-
$logger = $this->createMock(LoggerInterface::class);
189-
$logger
190-
->expects($this->atLeastOnce())
191-
->method($this->anything());
192-
193-
$cache = new TagAwareAdapter(new ArrayAdapter());
194-
$cache->setLogger($logger);
195-
196-
// Computing will produce at least one log
197-
$cache->get('foo', static function (): string { return 'ccc'; });
198-
199-
LockRegistry::setFiles($lockFiles);
200-
}
201-
202182
/**
203183
* @return MockObject&PruneableCacheInterface
204184
*/

src/Symfony/Component/Cache/Traits/ContractsTrait.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,20 @@ trait ContractsTrait
4141
*/
4242
public function setCallbackWrapper(?callable $callbackWrapper): callable
4343
{
44-
$previousWrapper = $this->callbackWrapper ??= \Closure::fromCallable([LockRegistry::class, 'compute']);
44+
if (!isset($this->callbackWrapper)) {
45+
$this->callbackWrapper = \Closure::fromCallable([LockRegistry::class, 'compute']);
46+
47+
if (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) {
48+
$this->setCallbackWrapper(null);
49+
}
50+
}
51+
4552
if (null !== $callbackWrapper && !$callbackWrapper instanceof \Closure) {
4653
$callbackWrapper = \Closure::fromCallable($callbackWrapper);
4754
}
4855

49-
$this->callbackWrapper = $callbackWrapper ?? function (callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata, ?LoggerInterface $logger) {
56+
$previousWrapper = $this->callbackWrapper;
57+
$this->callbackWrapper = $callbackWrapper ?? static function (callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata, ?LoggerInterface $logger) {
5058
return $callback($item, $save);
5159
};
5260

@@ -88,6 +96,10 @@ static function (CacheItem $item, float $startTime, ?array &$metadata) {
8896
$this->computing[$key] = $key;
8997
$startTime = microtime(true);
9098

99+
if (!isset($this->callbackWrapper)) {
100+
$this->setCallbackWrapper($this->setCallbackWrapper(null));
101+
}
102+
91103
try {
92104
$value = ($this->callbackWrapper)($callback, $item, $save, $pool, function (CacheItem $item) use ($setMetadata, $startTime, &$metadata) {
93105
$setMetadata($item, $startTime, $metadata);

src/Symfony/Component/DependencyInjection/Loader/PhpFileLoader.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ private function executeCallback(callable $callback, ContainerConfigurator $cont
135135
default:
136136
try {
137137
$configBuilder = $this->configBuilder($type);
138-
} catch (InvalidArgumentException | \LogicException $e) {
138+
} catch (InvalidArgumentException|\LogicException $e) {
139139
throw new \InvalidArgumentException(sprintf('Could not resolve argument "%s" for "%s".', $type.' $'.$parameter->getName(), $path), 0, $e);
140140
}
141141
$configBuilders[] = $configBuilder;

src/Symfony/Component/DomCrawler/Crawler.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,11 +1085,11 @@ private function convertToHtmlEntities(string $htmlContent, string $charset = 'U
10851085

10861086
try {
10871087
return mb_convert_encoding($htmlContent, 'HTML-ENTITIES', $charset);
1088-
} catch (\Exception | \ValueError $e) {
1088+
} catch (\Exception|\ValueError $e) {
10891089
try {
10901090
$htmlContent = iconv($charset, 'UTF-8', $htmlContent);
10911091
$htmlContent = mb_convert_encoding($htmlContent, 'HTML-ENTITIES', 'UTF-8');
1092-
} catch (\Exception | \ValueError $e) {
1092+
} catch (\Exception|\ValueError $e) {
10931093
}
10941094

10951095
return $htmlContent;

src/Symfony/Component/Dotenv/Dotenv.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ public function usePutenv(bool $usePutenv = true): static
7272
/**
7373
* Loads one or several .env files.
7474
*
75-
* @param string $path A file to load
76-
* @param ...string $extraPaths A list of additional files to load
75+
* @param string $path A file to load
76+
* @param string[] ...$extraPaths A list of additional files to load
7777
*
7878
* @throws FormatException when a file has a syntax error
7979
* @throws PathException when a file does not exist or is not readable
@@ -158,8 +158,8 @@ public function bootEnv(string $path, string $defaultEnv = 'dev', array $testEnv
158158
/**
159159
* Loads one or several .env files and enables override existing vars.
160160
*
161-
* @param string $path A file to load
162-
* @param ...string $extraPaths A list of additional files to load
161+
* @param string $path A file to load
162+
* @param string[] ...$extraPaths A list of additional files to load
163163
*
164164
* @throws FormatException when a file has a syntax error
165165
* @throws PathException when a file does not exist or is not readable

src/Symfony/Component/ErrorHandler/Resources/bin/extract-tentative-return-types.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class TentativeTypes
4040
4141
EOPHP;
4242

43-
while (false !== $file = fgets(STDIN)) {
43+
while (false !== $file = fgets(\STDIN)) {
4444
$code = file_get_contents(substr($file, 0, -1));
4545

4646
if (!str_contains($code, '@tentative-return-type')) {

src/Symfony/Component/Form/Command/DebugCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ private function completeOptions(string $class, CompletionSuggestions $suggestio
275275
if (!class_exists($class) || !is_subclass_of($class, FormTypeInterface::class)) {
276276
$classes = $this->getFqcnTypeClasses($class);
277277

278-
if (1 === count($classes)) {
278+
if (1 === \count($classes)) {
279279
$class = $classes[0];
280280
}
281281
}

src/Symfony/Component/HttpClient/HttpClient.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public static function create(array $defaultOptions = [], int $maxHostConnection
4444
$curlVersion = $curlVersion ?? curl_version();
4545

4646
// HTTP/2 push crashes before curl 7.61
47-
if (0x073d00 > $curlVersion['version_number'] || !(\CURL_VERSION_HTTP2 & $curlVersion['features'])) {
47+
if (0x073D00 > $curlVersion['version_number'] || !(\CURL_VERSION_HTTP2 & $curlVersion['features'])) {
4848
return new AmpHttpClient($defaultOptions, null, $maxHostConnections, $maxPendingPushes);
4949
}
5050
}

0 commit comments

Comments
 (0)
0