In some cases, while running in docker, we end up with:
```
[Errno 18] Invalid cross-device link: 'tmp<hash>' -> './assets/frappe'
```
Using `shutil.move` fixes this as it supports different filesystems, `os.replace` doesn't
Signed-off-by: Akhil Narang <me@akhilnarang.dev>
* perf: Restore dict's flat overrides
Using `super()` is unnecessary cost. This class is used A LOT. Ref: https://github.com/frappe/frappe/pull/16449/
Please consider performance while adding types, it's almost always possible to achieve good typing without this.
Also `frappe._dict` is almost always used as `dict[Any, Any]` or
`dict[str, Any]`, type annotations are useless here.
* ci: ugh wait for processes to exit
* perf: Use latest pickle protocol
* perf: pop flags from cached documents
This is also the right thing to do, things like `doc.flags.for_update`
shouldn't be "cached".
Developers can easily enable `can_cache` without knowing what it
entails. Public cache means proxy can likely cache things without
talking to backend.
Obviously many endpoints which can be cached on client side should
probably not be cached in proxy.
E.g. linked PR to the PR that added this feature suggest caching
notification log for short time... we don't want to leak one user's
cached notification to another user.
I don't buy that developers should know about cache implementation to
ensure it's secure or correct to enable it on certain endpoint. In
addition to that, we have very few mechanisms to burst cache
inside proxy. End user hitting ctrl+shift+r won't do anything if proxy
wants to serve stale response.
We should figure out better way to instruct FW about final cache
control headers than hardcoding it IMO.
* perf: Reduce impact of forced cache replacement on every doc access
* fix: clear cache before processing users
Note: This is just an artifact of testing model, this won't have any real
effect on execution in real system.
Basically `enqueue_on_commit` is not respected in tests and it can't be
practically supported either.
Sometimes we get invalid flags from `imap.uid()`, like `[b'System Error (Failure)']`
This leads to the flag getting parsed as 83 (`ord('S')`)
Signed-off-by: Akhil Narang <me@akhilnarang.dev>
- Eagerly initialize request_cache, all requests use it, so what is the
point of doing it lazily?
- Reduce accesses to `frappe.local` namespace, get cache once and reuse
it in rest of the execution.
Before: 1250ns +/- 1%
After: 645ns +/- 1%
Source: Trust me bro.
(no really, for now just trust me or look at the diff)
* perf(site_cache): reduce access to frappe.local namespace
This change also allows calling @site_cache during init, as long as `site` parameter is set.
* test: frappe.init patching
* perf: use monotonic time instead of realtime for eviction
datetime is complex, slow and not really required for this use case.
* perf!: Drop support for unhashable arguments
Just like LRU cache, no need to support unhashable types in site_cache.
Current usage in codebase also shows that it's not required and json.dumps is quite slow.
Just like LRU cache, no need to support unhashable types in site_cache.
Current usage in codebase also shows that it's not required and json.dumps is quite slow.
`get_doc` is single most used commands, directly and indirectly.
Currently there's QB overhead of building queries.
These queries are SO SIMPLE, I don't believe we need QB to keep these
maintainable or compatible with databases.
Microbenchmarks (first is simple flat document, second has many child tables):
```
bench_orm_bench_get_doc: Mean +- std dev: [before] 10.7 ms +- 0.2 ms -> [after] 7.24 ms +- 0.15 ms: 1.48x faster
bench_orm_bench_get_user: Mean +- std dev: [before] 16.3 ms +- 0.2 ms -> [after] 9.50 ms +- 0.14 ms: 1.72x faster
```
* fix: Don't cache anything hashable
If filters are list or dict then they aren't hashable, there was little
reason to do this IMO.
If something is indeed cacheable then where is the eviction for it?
simple k:v is only thing we can realistically cache here.
* ci: Dont specify client version
Clients work on mysql protocol ABI which works for huge ranges of
servers.
If filters are list or dict then they aren't hashable, there was little
reason to do this IMO.
If something is indeed cacheable then where is the eviction for it?
simple k:v is only thing we can realistically cache here.