* perf: No need to set expiry for key everytime
* fix: Set expiry on first request and never again
This prevents problem of rate limiter keys growing constantly.
Call it a new year's resolution.
`frappe/__init__.py` has grown crazy big over time and left unattended it will continue to grow.
This new ~test~ tax will require reducing 3 line per day (so ~1000 in a year) from 1st Jan 2025 onwards. I am offering a headstart of 50 days in this PR by moving ~150 lines: #28869
This is middle ground between caching it completely and requiring a
restart/signal to reload vs always reloading it.
I don't know any use cases that can break from this, nowhere in code
configs should be expected to reload instantly.
This change is only applied to requests for now
This makes maxsize deterministic while estimating memory costs of
using this function.
E.g. If I want to cache site config and I'd prefer to keep 16 recent
site configs in memory, there's no way to handle this. Site specific
maxsize means if I have 1000 sites on bench I'll have 1000 keys in
cache.
This change makes behaviour similar to lru_cache which is how I thought
it workerd TBH.
There is no gaurantee that setup_cache is only called once. This PR adds
a mutex lock to ensure only one thread gets to create the connection. If
both arrive at same time then one of them will be blocked until
connection is setup.
So far this hasn't been an issue because the "orphan" connection would
just get garbage collected but if you setup any kind of listener on it
or refer to it then it will keep running forever hurting performance.
This just has small performance impact on first request that sets up the
connection, in absence of contention the lock should have almost no
overhead. I make up for it by eliminating one function call :pinch:
RESP3 has PUSH support which is useful for implementing client side
caching. Enabling this before I work on that to test if anything breaks
with this.
No need to do this for background jobs instance just yet, infrequent
accesses and performance doesn't matter as much.
* perf: reuse current time
now_datetime is site-tz-aware, we don't need it here.
* perf: dont need redis transactions
* perf: use `time.time()` instead of datetime
Using `datetime.timestamp()` is a round-about way to use `time.time()`
with extra cost of dealing with datetime and timezones.
* perf: define slots for rate_limiter
* fix!: Remove used rate limit header
This just shares how much was consumed in current request, people can
just time requests to get an approximation for this, not sure why is this
useful.