Skip to content

Commit 09b56ed

Browse files
committed
bp/Control: randomize the EXPIRE_TCACHE_TAG delay
This completes commit 3739088
1 parent 57722d4 commit 09b56ed

5 files changed

Lines changed: 78 additions & 21 deletions

File tree

src/bp/Control.cxx

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "pool/pool.hxx"
2626
#include "net/SocketAddress.hxx"
2727
#include "io/Logger.hxx"
28+
#include "util/djb_hash.hxx"
2829
#include "util/SpanCast.hxx"
2930
#include "util/UnalignedBigEndian.hxx"
3031
#include "AllocatorPtr.hxx"
@@ -68,7 +69,8 @@ BpInstance::HandleTcacheInvalidate(std::span<const std::byte> payload) noexcept
6869
}
6970

7071
inline void
71-
BpInstance::OnExpireTcacheRA(const ResourceAddress &address) noexcept
72+
BpInstance::OnExpireTcacheRA(const ResourceAddress &address,
73+
Event::TimePoint time) noexcept
7274
{
7375
switch (address.type) {
7476
case ResourceAddress::Type::NONE:
@@ -85,8 +87,7 @@ BpInstance::OnExpireTcacheRA(const ResourceAddress &address) noexcept
8587
const TempPoolLease tpool;
8688
const auto key = lhttp.GetChildId(*tpool);
8789

88-
// TODO implement randomized delay
89-
lhttp_stock->FadeKey(key);
90+
lhttp_stock->ExpireKey(key, time);
9091
}
9192

9293
break;
@@ -97,8 +98,7 @@ BpInstance::OnExpireTcacheRA(const ResourceAddress &address) noexcept
9798
const TempPoolLease tpool;
9899
const auto key = cgi.GetChildId(*tpool);
99100

100-
// TODO implement randomized delay
101-
fcgi_stock->FadeKey(key);
101+
fcgi_stock->ExpireKey(key, time);
102102
}
103103
}
104104

@@ -111,16 +111,14 @@ BpInstance::OnExpireTcacheRA(const ResourceAddress &address) noexcept
111111
const TempPoolLease tpool;
112112
const auto key = cgi.GetChildId(*tpool);
113113

114-
// TODO implement randomized delay
115-
was_stock->FadeKey(key);
114+
was_stock->ExpireKey(key, time);
116115
}
117116
} else if (cgi.address_list.empty()) {
118117
if (multi_was_stock) {
119118
const TempPoolLease tpool;
120119
const auto key = cgi.GetChildId(*tpool);
121120

122-
// TODO implement randomized delay
123-
multi_was_stock->FadeKey(key);
121+
multi_was_stock->ExpireKey(key, time);
124122
}
125123
}
126124
#endif // HAVE_LIBWAS
@@ -129,12 +127,12 @@ BpInstance::OnExpireTcacheRA(const ResourceAddress &address) noexcept
129127
}
130128

131129
inline void
132-
BpInstance::OnExpireTcache(const TranslateResponse &response) noexcept
130+
BpInstance::OnExpireTcache(const TranslateResponse &response, Event::TimePoint time) noexcept
133131
{
134-
OnExpireTcacheRA(response.address);
132+
OnExpireTcacheRA(response.address, time);
135133

136134
for (const auto &view : response.views) {
137-
OnExpireTcacheRA(view.address);
135+
OnExpireTcacheRA(view.address, time);
138136

139137
for (const auto &transformation : view.transformations) {
140138
switch (transformation.type) {
@@ -144,7 +142,7 @@ BpInstance::OnExpireTcache(const TranslateResponse &response) noexcept
144142
break;
145143

146144
case Transformation::Type::FILTER:
147-
OnExpireTcacheRA(transformation.u.filter.address);
145+
OnExpireTcacheRA(transformation.u.filter.address, time);
148146
break;
149147
}
150148
}

src/bp/Instance.hxx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,10 @@ struct BpInstance final : PInstance, BengControl::Handler,
281281
void HandleExpireTcacheTag(std::span<const std::byte> payload) noexcept;
282282
void HandleDisableUring(std::span<const std::byte> payload) noexcept;
283283

284-
void OnExpireTcacheRA(const ResourceAddress &address) noexcept;
285-
void OnExpireTcache(const TranslateResponse &response) noexcept;
284+
void OnExpireTcacheRA(const ResourceAddress &address,
285+
Event::TimePoint time) noexcept;
286+
void OnExpireTcache(const TranslateResponse &response,
287+
Event::TimePoint time) noexcept;
286288

287289
/* virtual methods from class BengControl::Handler */
288290
void OnControlPacket(BengControl::Command command,

src/translation/Builder.hxx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#pragma once
66

7+
#include "event/Chrono.hxx"
78
#include "util/BindMethod.hxx"
89

910
#include <cstdint>
@@ -56,7 +57,8 @@ class TranslationCacheBuilder final : public TranslationServiceBuilder {
5657
std::map<SocketAddress, std::shared_ptr<TranslationCache>,
5758
SocketAddressCompare> m;
5859

59-
using ExpireCallback = BoundMethod<void(const TranslateResponse &response) noexcept>;
60+
using ExpireCallback = BoundMethod<void(const TranslateResponse &response,
61+
Event::TimePoint time) noexcept>;
6062

6163
public:
6264
TranslationCacheBuilder(TranslationStockBuilder &_builder,

src/translation/Cache.cxx

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "io/Logger.hxx"
2727
#include "util/djb_hash.hxx"
2828
#include "util/IntrusiveForwardList.hxx"
29+
#include "util/RoundPowerOfTwo.hxx"
2930
#include "util/SpanCast.hxx"
3031
#include "util/StringAPI.hxx"
3132
#include "util/StringSplit.hxx"
@@ -886,13 +887,60 @@ TranslationCache::Invalidate(const TranslateRequest &request,
886887
LogConcat(4, "TranslationCache", "invalidated ", removed, " cache items");
887888
}
888889

890+
/**
891+
* Overload for RoundUpToPowerOfTwo() (from
892+
* `util/RoundPowerOfTwo.hxx`) which takes/returns an Event::Duration.
893+
*/
894+
static constexpr Event::Duration
895+
RoundUpToPowerOfTwo(Event::Duration value) noexcept
896+
{
897+
using rep = Event::Duration::rep;
898+
using unsigned_rep = std::make_unsigned_t<rep>;
899+
900+
const auto scalar = RoundUpToPowerOfTwo(static_cast<unsigned_rep>(value.count()));
901+
return Event::Duration{static_cast<rep>(scalar)};
902+
}
903+
904+
/**
905+
* Calculate an EXPIRE_TCACHE_TAG delay for the specified SITE string.
906+
* All translation cache items and child processes for this site shall
907+
* expire at the same time, but each site should get a different
908+
* expiry.
909+
*/
910+
static constexpr Event::Duration
911+
CalculateExpireDelayForSite(const char *site) noexcept
912+
{
913+
if (site == nullptr)
914+
return {};
915+
916+
/**
917+
* An approximation for the maximum delay, the range over
918+
* which all sites are going to be distributed.
919+
*/
920+
static constexpr Event::Duration APPROXIMATE_MAX_DELAY = std::chrono::minutes{5};
921+
922+
/**
923+
* This is the real maximum delay, calculated as the next
924+
* power of two, which can then be used to derive a bit mask
925+
* to be applied to the site hash with bit-wise "and".
926+
*/
927+
static constexpr Event::Duration MAX_DELAY = RoundUpToPowerOfTwo(APPROXIMATE_MAX_DELAY);
928+
static constexpr std::size_t MASK = MAX_DELAY.count() - 1;
929+
930+
const std::size_t hash = djb_hash_string(site);
931+
return Event::Duration(hash & MASK);
932+
}
933+
889934
void
890935
TranslationCache::ExpireTag(std::string_view tag, ExpireCallback callback) noexcept
891936
{
892-
per_tag.remove_and_dispose_key(tag, [this, callback](TranslateCacheItemTag *item_tag){
893-
auto &item = item_tag->parent;
894-
callback(item.response);
895-
cache.Remove(item);
937+
const auto now = cache.SteadyNow();
938+
per_tag.for_each_key(tag, [callback, now](TranslateCacheItemTag &item_tag){
939+
auto &item = item_tag.parent;
940+
const auto delay = CalculateExpireDelayForSite(item.response.site);
941+
const auto expires = now + delay;
942+
item.SetExpires(expires);
943+
callback(item.response, expires);
896944
});
897945
}
898946

src/translation/Cache.hxx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "cache/Handler.hxx"
1010
#include "pool/Ptr.hxx"
1111
#include "stats/CacheStats.hxx"
12+
#include "event/Chrono.hxx"
1213
#include "memory/SlicePool.hxx"
1314
#include "util/BindMethod.hxx"
1415
#include "util/IntrusiveHashSet.hxx"
@@ -112,7 +113,13 @@ class TranslationCache final : public TranslationService, CacheHandler {
112113
*/
113114
bool active;
114115

115-
using ExpireCallback = BoundMethod<void(const TranslateResponse &response) noexcept>;
116+
/**
117+
* @param time the time point when resources (e.g. child
118+
* processes) described by this #TranslateResponse shall
119+
* expire
120+
*/
121+
using ExpireCallback = BoundMethod<void(const TranslateResponse &response,
122+
Event::TimePoint time) noexcept>;
116123

117124
public:
118125
/**

0 commit comments

Comments
 (0)