Closed epifeny closed 3 months ago
The setting is per project and resets on restart of the server.
The setting is per project and resets on restart of the server.
Thanks for your reply. Per project you mean individually for requests, charset_normalizer, idna, urllib3 and certifi? I mean, they all keep checking pypi.org even though they have been downloaded and haven't changed.
The server hasn't been restarted. It's the same running instance.
The setting is per project and resets on restart of the server.
Here, you can see that I keep trying to install just certifi and the server keeps checking pypi.org over and over again
2024-07-11 05:32:59,406 INFO [req144] GET /devpi/dev/certifi/
2024-07-11 05:32:59,416 INFO [req145] GET /devpi/dev/certifi
2024-07-11 05:32:59,430 INFO HTTP Request: GET https://pypi.org/simple/certifi/ "HTTP/1.1 304 Not Modified"
2024-07-11 05:32:59,483 INFO [req146] GET /root/pypi/+f/c19/8e21b1289c2ab/certifi-2024.7.4-py3-none-any.whl
2024-07-11 05:33:24,867 INFO [req147] GET /devpi/dev/certifi/
2024-07-11 05:33:24,876 INFO [req148] GET /devpi/dev/certifi
2024-07-11 05:33:24,891 INFO HTTP Request: GET https://pypi.org/simple/certifi/ "HTTP/1.1 304 Not Modified"
2024-07-11 05:33:24,932 INFO [req149] GET /root/pypi/+f/c19/8e21b1289c2ab/certifi-2024.7.4-py3-none-any.whl
2024-07-11 05:33:29,345 INFO [req150] GET /devpi/dev/certifi/
2024-07-11 05:33:29,354 INFO [req151] GET /devpi/dev/certifi
2024-07-11 05:33:29,368 INFO HTTP Request: GET https://pypi.org/simple/certifi/ "HTTP/1.1 304 Not Modified"
2024-07-11 05:33:29,440 INFO [req152] GET /root/pypi/+f/c19/8e21b1289c2ab/certifi-2024.7.4-py3-none-any.whl
2024-07-11 05:33:33,475 INFO [req153] GET /devpi/dev/certifi/
2024-07-11 05:33:33,483 INFO [req154] GET /devpi/dev/certifi
2024-07-11 05:33:33,498 INFO HTTP Request: GET https://pypi.org/simple/certifi/ "HTTP/1.1 304 Not Modified"
2024-07-11 05:33:33,537 INFO [req155] GET /root/pypi/+f/c19/8e21b1289c2ab/certifi-2024.7.4-py3-none-any.whl
Could you try the same directly on /root/pypi/certifi instead of going through /devpi/dev/certifi which seems to inherit from root/pypi?
Could you try the same directly on /root/pypi/certifi instead of going through /devpi/dev/certifi which seems to inherit from root/pypi?
It's the same issue
2024-07-11 05:56:49,852 INFO [req168] GET /root/pypi/certifi/
2024-07-11 05:56:49,861 INFO [req169] GET /root/pypi/certifi
2024-07-11 05:56:49,880 INFO HTTP Request: GET https://pypi.org/simple/certifi/ "HTTP/1.1 304 Not Modified"
2024-07-11 05:56:49,919 INFO [req170] GET /root/pypi/+f/c19/8e21b1289c2ab/certifi-2024.7.4-py3-none-any.whl
2024-07-11 05:56:58,512 INFO [req171] GET /root/pypi/certifi/
2024-07-11 05:56:58,522 INFO [req172] GET /root/pypi/certifi
2024-07-11 05:56:58,541 INFO HTTP Request: GET https://pypi.org/simple/certifi/ "HTTP/1.1 304 Not Modified"
2024-07-11 05:56:58,615 INFO [req173] GET /root/pypi/+f/c19/8e21b1289c2ab/certifi-2024.7.4-py3-none-any.whl
2024-07-11 05:57:17,277 INFO [req174] GET /root/pypi/certifi/
2024-07-11 05:57:17,287 INFO [req175] GET /root/pypi/certifi
2024-07-11 05:57:17,304 INFO HTTP Request: GET https://pypi.org/simple/certifi/ "HTTP/1.1 304 Not Modified"
2024-07-11 05:57:17,357 INFO [req176] GET /root/pypi/+f/c19/8e21b1289c2ab/certifi-2024.7.4-py3-none-any.whl
2024-07-11 05:57:30,727 INFO [req177] GET /root/pypi/certifi/
2024-07-11 05:57:30,736 INFO [req178] GET /root/pypi/certifi
2024-07-11 05:57:30,754 INFO HTTP Request: GET https://pypi.org/simple/certifi/ "HTTP/1.1 304 Not Modified"
2024-07-11 05:57:30,806 INFO [req179] GET /root/pypi/+f/c19/8e21b1289c2ab/certifi-2024.7.4-py3-none-any.whl
I decided to recreate everything from scratch and can't reproduce the issue I had.
I actually got this happening again. I have the server running for nearly a week, and all the packages are again showing 304. devpi server keeps checking pypi.org for every package.
2024-07-23 11:02:54,643 INFO [req42959] GET /root/pypi/certifi/
2024-07-23 11:02:54,659 INFO [req42960] GET /root/pypi/certifi
2024-07-23 11:02:54,702 INFO HTTP Request: GET https://pypi.org/simple/certifi/ "HTTP/1.1 304 Not Modified"
2024-07-23 11:02:54,763 INFO [req42961] GET /root/pypi/+f/c19/8e21b1289c2ab/certifi-2024.7.4-py3-none-any.whl
This is the process
# ps auxfww | grep -v grep | grep devpi-server
root 1 0.3 0.2 4596456 1129620 ? Ssl Jul17 34:20 /usr/local/bin/python /usr/local/bin/devpi-server --serverdir /opt/devpi-server/data --host 0.0.0.0 --port 3141 --mirror-cache-expiry 43200
It certainly looks like it doesn't happen right away. I see the same behavior on https://m.devpi.net which is running for a while now. I can't reproduce it locally yet.
To quickly reproduce the problem use --mirror-cache-expiry=10
.
With devpi-web it is even worse, as it causes a HEAD request for each version of the package.
Could you test with this change:
diff --git a/server/devpi_server/mirror.py b/server/devpi_server/mirror.py
index f29a6d5df..8d37fa73b 100644
--- a/server/devpi_server/mirror.py
+++ b/server/devpi_server/mirror.py
@@ -795,8 +795,8 @@ class MirrorStage(BaseStage):
f"timeout after {self.timeout} seconds while getting data for {project!r}")
except self.UpstreamNotModified as e:
if links is not None:
- self.keyfs.tx.on_commit_success(partial(
- self.cache_retrieve_times.refresh, project, e.etag))
+ # immediately update the cache
+ self.cache_retrieve_times.refresh(project, e.etag)
return self.SimpleLinks(links)
if e.etag is None:
threadlog.error(
It's been around 8 hours since I started the server, not 304 Not Modified
yet. Just a few expected 200 OK
.
I will continue to monitor this and see when I start getting 304 Not Modified
, maybe it's related to what I have defined in the --mirror-cache-expiry 43200
.
I'll keep you posted.
To quickly reproduce the problem use
--mirror-cache-expiry=10
.With devpi-web it is even worse, as it causes a HEAD request for each version of the package.
Could you test with this change:
diff --git a/server/devpi_server/mirror.py b/server/devpi_server/mirror.py index f29a6d5df..8d37fa73b 100644 --- a/server/devpi_server/mirror.py +++ b/server/devpi_server/mirror.py @@ -795,8 +795,8 @@ class MirrorStage(BaseStage): f"timeout after {self.timeout} seconds while getting data for {project!r}") except self.UpstreamNotModified as e: if links is not None: - self.keyfs.tx.on_commit_success(partial( - self.cache_retrieve_times.refresh, project, e.etag)) + # immediately update the cache + self.cache_retrieve_times.refresh(project, e.etag) return self.SimpleLinks(links) if e.etag is None: threadlog.error(
Yes. I will try it out but it's not gonna be easy since I'm running it via Kuberenetes and pushing a change into a file inside a pod is going to be challenging. I would rather you test it, push a fix with an update to the devpi-server package that I can install and test.
I started the server with --mirror-cache-expiry 5
:
# ps auxfww | grep -v grep | grep devpi
root 1 115 0.1 4648436 616040 ? Ssl 20:56 2:50 /usr/local/bin/python /usr/local/bin/devpi-server --serverdir /opt/devpi-server/data --host 0.0.0.0 --port 3141 --mirror-cache-expiry 5
with the change in place:
# grep -C 10 'immediately update the cache' /usr/local/lib/python3.12/site-packages/devpi_server/mirror.py
self._update_simplelinks_in_future(newlinks_future, project, lock.defer()))
if links is not None:
threadlog.warn(
"serving stale links for %r, getting data timed out after %s seconds",
project, self.timeout)
return self.SimpleLinks(links, stale=True)
raise self.UpstreamError(
f"timeout after {self.timeout} seconds while getting data for {project!r}")
except self.UpstreamNotModified as e:
if links is not None:
# immediately update the cache
self.cache_retrieve_times.refresh(project, e.etag)
return self.SimpleLinks(links)
if e.etag is None:
threadlog.error(
"server returned 304 Not Modified, but we have no links")
raise
# should not happen, but clear ETag and try again
self.cache_retrieve_times.expire(project, etag=None)
return self.get_simplelinks_perstage(project)
except (self.UpstreamNotFoundError, self.UpstreamError) as e:
at this time it started serving:
2024-07-23 20:56:36,599 INFO Serving on http://0.0.0.0:3141
and just a few moments after, I started getting 304:
2024-07-23 20:56:43,881 INFO HTTP Request: GET https://pypi.org/simple/requests/ "HTTP/1.1 200 OK"
2024-07-23 20:56:44,218 INFO HTTP Request: GET https://pypi.org/simple/certifi/ "HTTP/1.1 200 OK"
2024-07-23 20:56:44,465 INFO HTTP Request: GET https://pypi.org/simple/charset-normalizer/ "HTTP/1.1 200 OK"
2024-07-23 20:56:45,205 INFO HTTP Request: GET https://pypi.org/simple/urllib3/ "HTTP/1.1 200 OK"
2024-07-23 20:56:45,404 INFO HTTP Request: GET https://pypi.org/simple/idna/ "HTTP/1.1 200 OK"
2024-07-23 20:57:07,094 INFO HTTP Request: GET https://pypi.org/simple/requests/ "HTTP/1.1 304 Not Modified"
2024-07-23 20:57:07,299 INFO HTTP Request: GET https://pypi.org/simple/charset-normalizer/ "HTTP/1.1 304 Not Modified"
2024-07-23 20:57:07,574 INFO HTTP Request: GET https://pypi.org/simple/certifi/ "HTTP/1.1 304 Not Modified"
2024-07-23 20:57:07,693 INFO HTTP Request: GET https://pypi.org/simple/urllib3/ "HTTP/1.1 304 Not Modified"
2024-07-23 20:57:07,835 INFO HTTP Request: GET https://pypi.org/simple/idna/ "HTTP/1.1 304 Not Modified"
2024-07-23 20:57:20,289 INFO HTTP Request: GET https://pypi.org/simple/requests/ "HTTP/1.1 304 Not Modified"
2024-07-23 20:57:20,523 INFO HTTP Request: GET https://pypi.org/simple/idna/ "HTTP/1.1 304 Not Modified"
2024-07-23 20:57:20,676 INFO HTTP Request: GET https://pypi.org/simple/urllib3/ "HTTP/1.1 304 Not Modified"
2024-07-23 20:57:20,874 INFO HTTP Request: GET https://pypi.org/simple/certifi/ "HTTP/1.1 304 Not Modified"
2024-07-23 20:57:21,073 INFO HTTP Request: GET https://pypi.org/simple/charset-normalizer/ "HTTP/1.1 304 Not Modified"
With just 5 seconds the 304s are expected as is indicated by the time difference. Please try with the patch, but with the default expiry.
You're absolutely correct! I intended to set it to 5 minutes but didn't remember that this variable is in seconds, not minutes. I've now set it to 120 seconds to do a quick test. The cache expires every 120 seconds, so devpi-server does a recheck on the metadata as expected.
2024-07-24 06:07:36,870 INFO HTTP Request: GET https://pypi.org/simple/requests/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:07:37,146 INFO HTTP Request: GET https://pypi.org/simple/idna/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:07:37,373 INFO HTTP Request: GET https://pypi.org/simple/certifi/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:07:37,568 INFO HTTP Request: GET https://pypi.org/simple/urllib3/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:07:37,760 INFO HTTP Request: GET https://pypi.org/simple/charset-normalizer/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:09:46,239 INFO HTTP Request: GET https://pypi.org/simple/requests/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:09:46,553 INFO HTTP Request: GET https://pypi.org/simple/urllib3/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:09:46,739 INFO HTTP Request: GET https://pypi.org/simple/charset-normalizer/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:09:47,087 INFO HTTP Request: GET https://pypi.org/simple/certifi/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:09:47,216 INFO HTTP Request: GET https://pypi.org/simple/idna/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:11:47,437 INFO HTTP Request: GET https://pypi.org/simple/requests/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:11:47,825 INFO HTTP Request: GET https://pypi.org/simple/certifi/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:11:48,079 INFO HTTP Request: GET https://pypi.org/simple/urllib3/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:11:48,237 INFO HTTP Request: GET https://pypi.org/simple/charset-normalizer/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:11:48,644 INFO HTTP Request: GET https://pypi.org/simple/idna/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:13:58,135 INFO HTTP Request: GET https://pypi.org/simple/requests/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:13:58,279 INFO HTTP Request: GET https://pypi.org/simple/idna/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:13:58,598 INFO HTTP Request: GET https://pypi.org/simple/certifi/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:13:58,851 INFO HTTP Request: GET https://pypi.org/simple/charset-normalizer/ "HTTP/1.1 304 Not Modified"
2024-07-24 06:13:59,309 INFO HTTP Request: GET https://pypi.org/simple/urllib3/ "HTTP/1.1 304 Not Modified"
I am experiencing an issue with the devpi-server where it appears not to respect the --mirror-cache-expiry argument. Despite setting the --mirror-cache-expiry to 43200 seconds (12 hours), the server continues to check pypi.org for updates instead of waiting for the specified cache expiry time.
Steps to Reproduce:
Start the devpi-server with the following command:
Verify that the process is running with the expected arguments:
Client Side:
Set up a Python virtual environment and activate it:
Install a package using the devpi-server:
Expected Behavior:
The devpi-server should wait for the allotted --mirror-cache-expiry time (12 hours) before checking pypi.org for updates.
Actual Behavior:
The server checks pypi.org for updates more frequently than the specified --mirror-cache-expiry time.
Environment:
Installed Packages:
Server Logs:
Question:
What am I doing wrong, or what did I not fully understand about the --mirror-cache-expiry argument?
Thank you for your assistance.