Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ae7803d

Browse files
Merge branch '4.4'
* 4.4: [Serializer] fix typo Add context options to handle BOM [Mailer] Fix Message ID for Postmark SMTP [HttpClient] resolve promise chains on HttplugClient::wait() Add Message-Id to SentMessage when sending an email [Cache] fix 2RTT + race condition in AbstractTagAwareAdapter::deleteItems() [Mailer] added ReplyTo option for PostmarkApiTransport
2 parents a306d99 + a876748 commit ae7803d

24 files changed

+385
-206
lines changed

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

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,18 @@ abstract protected function doSave(array $values, int $lifetime, array $addTagDa
133133
/**
134134
* Removes multiple items from the pool and their corresponding tags.
135135
*
136-
* @param array $ids An array of identifiers that should be removed from the pool
137-
* @param array $tagData Optional array of tag identifiers => key identifiers that should be removed from the pool
136+
* @param array $ids An array of identifiers that should be removed from the pool
138137
*
139138
* @return bool True if the items were successfully removed, false otherwise
140139
*/
141-
abstract protected function doDelete(array $ids, array $tagData = []): bool;
140+
abstract protected function doDelete(array $ids);
141+
142+
/**
143+
* Removes relations between tags and deleted items.
144+
*
145+
* @param array $tagData Array of tag => key identifiers that should be removed from the pool
146+
*/
147+
abstract protected function doDeleteTagRelations(array $tagData): bool;
142148

143149
/**
144150
* Invalidates cached items using tags.
@@ -150,21 +156,21 @@ abstract protected function doDelete(array $ids, array $tagData = []): bool;
150156
abstract protected function doInvalidate(array $tagIds): bool;
151157

152158
/**
153-
* Returns the tags bound to the provided ids.
159+
* Delete items and yields the tags they were bound to.
154160
*/
155-
protected function doFetchTags(array $ids): iterable
161+
protected function doDeleteYieldTags(array $ids): iterable
156162
{
157163
foreach ($this->doFetch($ids) as $id => $value) {
158164
yield $id => \is_array($value) && \is_array($value['tags'] ?? null) ? $value['tags'] : [];
159165
}
166+
167+
$this->doDelete($ids);
160168
}
161169

162170
/**
163171
* {@inheritdoc}
164-
*
165-
* @return bool
166172
*/
167-
public function commit()
173+
public function commit(): bool
168174
{
169175
$ok = true;
170176
$byLifetime = $this->mergeByLifetime;
@@ -223,17 +229,14 @@ public function commit()
223229

224230
/**
225231
* {@inheritdoc}
226-
*
227-
* Overloaded in order to deal with tags for adjusted doDelete() signature.
228-
*
229-
* @return bool
230232
*/
231-
public function deleteItems(array $keys)
233+
public function deleteItems(array $keys): bool
232234
{
233235
if (!$keys) {
234236
return true;
235237
}
236238

239+
$ok = true;
237240
$ids = [];
238241
$tagData = [];
239242

@@ -243,24 +246,22 @@ public function deleteItems(array $keys)
243246
}
244247

245248
try {
246-
foreach ($this->doFetchTags($ids) as $id => $tags) {
249+
foreach ($this->doDeleteYieldTags(array_values($ids)) as $id => $tags) {
247250
foreach ($tags as $tag) {
248251
$tagData[$this->getId(self::TAGS_PREFIX.$tag)][] = $id;
249252
}
250253
}
251254
} catch (\Exception $e) {
252-
// ignore unserialization failures
255+
$ok = false;
253256
}
254257

255258
try {
256-
if ($this->doDelete(array_values($ids), $tagData)) {
259+
if ((!$tagData || $this->doDeleteTagRelations($tagData)) && $ok) {
257260
return true;
258261
}
259262
} catch (\Exception $e) {
260263
}
261264

262-
$ok = true;
263-
264265
// When bulk-delete failed, retry each item individually
265266
foreach ($ids as $key => $id) {
266267
try {

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

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ class FilesystemTagAwareAdapter extends AbstractTagAwareAdapter implements Prune
2727
use FilesystemTrait {
2828
doClear as private doClearCache;
2929
doSave as private doSaveCache;
30-
doDelete as private doDeleteCache;
3130
}
3231

3332
/**
@@ -133,14 +132,19 @@ protected function doSave(array $values, int $lifetime, array $addTagData = [],
133132
/**
134133
* {@inheritdoc}
135134
*/
136-
protected function doFetchTags(array $ids): iterable
135+
protected function doDeleteYieldTags(array $ids): iterable
137136
{
138137
foreach ($ids as $id) {
139138
$file = $this->getFile($id);
140139
if (!file_exists($file) || !$h = @fopen($file, 'rb')) {
141140
continue;
142141
}
143142

143+
if ((\PHP_VERSION_ID >= 70300 || '\\' !== \DIRECTORY_SEPARATOR) && !@unlink($file)) {
144+
fclose($h);
145+
continue;
146+
}
147+
144148
$meta = explode("\n", fread($h, 4096), 3)[2] ?? '';
145149

146150
// detect the compact format used in marshall() using magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F
@@ -161,25 +165,26 @@ protected function doFetchTags(array $ids): iterable
161165
}
162166

163167
fclose($h);
168+
169+
if (\PHP_VERSION_ID < 70300 && '\\' === \DIRECTORY_SEPARATOR) {
170+
@unlink($file);
171+
}
164172
}
165173
}
166174

167175
/**
168176
* {@inheritdoc}
169177
*/
170-
protected function doDelete(array $ids, array $tagData = []): bool
178+
protected function doDeleteTagRelations(array $tagData): bool
171179
{
172-
$ok = $this->doDeleteCache($ids);
173-
174-
// Remove tags
175-
foreach ($tagData as $tagId => $idMap) {
180+
foreach ($tagData as $tagId => $idList) {
176181
$tagFolder = $this->getTagFolder($tagId);
177-
foreach ($idMap as $id) {
182+
foreach ($idList as $id) {
178183
@unlink($this->getFile($id, false, $tagFolder));
179184
}
180185
}
181186

182-
return $ok;
187+
return true;
183188
}
184189

185190
/**

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

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,11 @@ protected function doSave(array $values, int $lifetime, array $addTagData = [],
123123
/**
124124
* {@inheritdoc}
125125
*/
126-
protected function doFetchTags(array $ids): iterable
126+
protected function doDeleteYieldTags(array $ids): iterable
127127
{
128128
$lua = <<<'EOLUA'
129129
local v = redis.call('GET', KEYS[1])
130+
redis.call('DEL', KEYS[1])
130131
131132
if not v or v:len() <= 13 or v:byte(1) ~= 0x9D or v:byte(6) ~= 0 or v:byte(10) ~= 0x5F then
132133
return ''
@@ -159,25 +160,12 @@ protected function doFetchTags(array $ids): iterable
159160
/**
160161
* {@inheritdoc}
161162
*/
162-
protected function doDelete(array $ids, array $tagData = []): bool
163+
protected function doDeleteTagRelations(array $tagData): bool
163164
{
164-
if (!$ids) {
165-
return true;
166-
}
167-
168-
$predisCluster = $this->redis instanceof \Predis\ClientInterface && $this->redis->getConnection() instanceof PredisCluster;
169-
$this->pipeline(static function () use ($ids, $tagData, $predisCluster) {
170-
if ($predisCluster) {
171-
// Unlike phpredis, Predis does not handle bulk calls for us against cluster
172-
foreach ($ids as $id) {
173-
yield 'del' => [$id];
174-
}
175-
} else {
176-
yield 'del' => $ids;
177-
}
178-
165+
$this->pipeline(static function () use ($tagData) {
179166
foreach ($tagData as $tagId => $idList) {
180-
yield 'sRem' => array_merge([$tagId], $idList);
167+
array_unshift($idList, $tagId);
168+
yield 'sRem' => $idList;
181169
}
182170
})->rewind();
183171

0 commit comments

Comments
 (0)