Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MaxMind GeoLite2 infinite download attempts - problem still exists with 4.0.2 #2114

Closed
oliversturm opened this issue Apr 29, 2024 · 14 comments
Closed
Labels

Comments

@oliversturm
Copy link

Shlink version

4.0.2

PHP version

8.3.3

How do you serve Shlink

Docker image

Database engine

MariaDB

Database version

11.3.2

Current behavior

I see the exact behavior described in #2021 -- received notification from Maxmind yesterday, log on their end shows countless downloads each of the last few days (I guess they are not countless but rather 30, but I didn't count). Log on my host shows many successful downloads for no apparent reason, until eventually a download fails because the limit is reached. Further downloads fail with a 429. Just summarizing here -- I read the thread in #2021 and I see that exact thing.

The snag is: I'm already using 4.0.2.

2024-04-29-000758@2x

Am I the only one?

Expected behavior

GeoIP db to be downloaded only as needed, or at least limited to Maxmind Free tier compatible attempts per day.

Minimum steps to reproduce

Good questions. Like others, I had this setup running for a long while without trouble. I updated on March 15th and went to 4.0.2, and (I just checked) the first time MaxMind complained by email about the database download limit was also March 15th. Strangely, nothing happened after that, until I received new warning emails on April 19th, 23rd and 28th.

@acelaya
Copy link
Member

acelaya commented Apr 29, 2024

Unfortunately I'm gonna need more details if we want to get to the bottom of this. If your answer to Minimum steps to reproduce is Good questions, I'm sure you understand it's going to be impossible for me to test anything 😅

Perhaps a docker-compose file including a configuration as close as possible to how you run Shlink, would be helpful.

If you could share logs showcasing those download attempts, that would also be great. The keywords to look for are GeoLite2 database download failed.

@oliversturm
Copy link
Author

Right, no problem. I didn't really think I could be the only one who still had this problem. Thanks for replying, I'll do my best to find all the necessary information.

The section of my docker compose file looks like this:

  shlink:
    image: shlinkio/shlink:stable
    restart: unless-stopped
    container_name: shlink
    depends_on:
      - maria
    environment:
      DEFAULT_DOMAIN: mydomain.com
      IS_HTTPS_ENABLED: "true"
      DB_DRIVER: maria
      DB_USER: root
      DB_PASSWORD: mariarootpwd
      DB_HOST: maria
      GEOLITE_LICENSE_KEY: mylicensekey

Looking at the logs, I notice that for weeks before April 16th, there was no attempt to update the database file. I can see that I had similar errors before March 15th, though the wording was different then ("Finished downloading GeoLite2 db file" instead of "Finished updating GeoLite2 db file"). However, these messages stop on March 15th, when I updated to 4.0.2, and then only started again on April 16th. Perhaps not a coincidence that there's close to one month in between?

Suddenly on the 16th an update takes place, perhaps triggered by the GET request to /.

As you can see, this happens again shortly afterwards, and continues from there.

Log file snippet from April 16th
shlink  | 2024-04-16T14:09:58+0000	INFO	server      	[2024-04-16T14:09:58.220670+00:00] [353d22aa-3575-41d9-bea4-66cc044d48a4] Access.INFO - GET / 302 0
shlink  | 2024-04-16T15:13:19+0000	DEBUG	jobs        	job was pushed successfully	{"ID": "0f871d12-a160-4f8b-a280-115780b0fefa", "pipeline": "shlink", "driver": "memory", "start": "2024-04-16T15:13:19+0000", "elapsed": 0}
shlink  | {"level":"debug","ts":1713280399486419534,"logger":"memory","msg":"message pushed to the priority queue","current":1,"limit":10}
shlink  | 2024-04-16T15:13:19+0000	DEBUG	jobs        	job processing was started	{"ID": "0f871d12-a160-4f8b-a280-115780b0fefa", "start": "2024-04-16T12:27:51+0000", "elapsed": 9927689}
shlink  | 2024-04-16T15:13:19+0000	INFO	server      	[2024-04-16T15:13:19.501507+00:00] [708e6557-5925-4db9-b0fc-107535e29b55] Access.INFO - GET / 302 0
shlink  | 2024-04-16T15:13:19+0000	INFO	server      	[2024-04-16T15:13:19.509152+00:00] [-] Shlink.NOTICE - Updating GeoLite2 db file...
shlink  | 
shlink  | 2024-04-16T15:13:19+0000	INFO	server      	[2024-04-16T15:13:19.694318+00:00] [-] Shlink.NOTICE - Finished updating GeoLite2 db file
shlink  | 
shlink  | 2024-04-16T15:13:23+0000	DEBUG	jobs        	job was processed successfully	{"ID": "0f871d12-a160-4f8b-a280-115780b0fefa", "start": "2024-04-16T12:27:51+0000", "elapsed": 9931584}
shlink  | 2024-04-16T15:14:58+0000	DEBUG	jobs        	job was pushed successfully	{"ID": "8b1d70cf-2dcd-40b9-a185-599fd3a87579", "pipeline": "shlink", "driver": "memory", "start": "2024-04-16T15:14:58+0000", "elapsed": 0}
shlink  | {"level":"debug","ts":1713280498387641538,"logger":"memory","msg":"message pushed to the priority queue","current":1,"limit":10}
shlink  | 2024-04-16T15:14:58+0000	DEBUG	jobs        	job processing was started	{"ID": "8b1d70cf-2dcd-40b9-a185-599fd3a87579", "start": "2024-04-16T13:45:01+0000", "elapsed": 5396398}
shlink  | 2024-04-16T15:14:58+0000	INFO	server      	[2024-04-16T15:14:58.407331+00:00] [-] Shlink.NOTICE - Updating GeoLite2 db file...
shlink  | [2024-04-16T15:14:58.408193+00:00] [-] Shlink.NOTICE - Finished updating GeoLite2 db file
shlink  | 
shlink  | 2024-04-16T15:14:58+0000	INFO	server      	[2024-04-16T15:14:58.412991+00:00] [4b243978-26a4-4499-9457-f03078f4bd71] Access.INFO - GET / 302 0
shlink  | 2024-04-16T15:14:59+0000	DEBUG	jobs        	job was processed successfully	{"ID": "8b1d70cf-2dcd-40b9-a185-599fd3a87579", "start": "2024-04-16T13:45:01+0000", "elapsed": 5397825}
shlink  | 2024-04-16T15:16:37+0000	DEBUG	jobs        	job was pushed successfully	{"ID": "88d4ea2f-20fc-489e-861e-0b3e3fcf04fa", "pipeline": "shlink", "driver": "memory", "start": "2024-04-16T15:16:37+0000", "elapsed": 0}
shlink  | {"level":"debug","ts":1713280597292681673,"logger":"memory","msg":"message pushed to the priority queue","current":1,"limit":10}
shlink  | 2024-04-16T15:16:37+0000	DEBUG	jobs        	job processing was started	{"ID": "88d4ea2f-20fc-489e-861e-0b3e3fcf04fa", "start": "2024-04-16T14:09:58+0000", "elapsed": 3999079}
shlink  | 2024-04-16T15:16:37+0000	INFO	server      	[2024-04-16T15:16:37.294478+00:00] [-] Shlink.NOTICE - Updating GeoLite2 db file...
shlink  | [2024-04-16T15:16:37.295111+00:00] [-] Shlink.NOTICE - Finished updating GeoLite2 db file
shlink  | 
shlink  | 2024-04-16T15:16:37+0000	INFO	server      	[2024-04-16T15:16:37.301359+00:00] [370eac77-488d-466b-9171-b459c66d417e] Access.INFO - GET / 302 0
shlink  | 2024-04-16T15:16:38+0000	DEBUG	jobs        	job was processed successfully	{"ID": "88d4ea2f-20fc-489e-861e-0b3e3fcf04fa", "start": "2024-04-16T14:09:58+0000", "elapsed": 4000380}
shlink  | {"level":"debug","ts":1713280668146233566,"logger":"static","msg":"no such file or directory","error":"open ../../public/robots.txt: no such file or directory"}

Now, I used some manual greps to find out how often this happened each day.

> grep -e '2024-04-16.*Finished updating GeoLite2 db file' 20240429-shlink.log | wc -l
      10

> grep -e '2024-04-17.*Finished updating GeoLite2 db file' 20240429-shlink.log | wc -l
      21

> grep -e '2024-04-18.*Finished updating GeoLite2 db file' 20240429-shlink.log | wc -l
      16

> grep -e '2024-04-19.*Finished updating GeoLite2 db file' 20240429-shlink.log | wc -l
     105

Obviously the number is suddenly much greater on the 19th, so I checked out that date. Initially everything looks like before, many successful downloads. Then suddenly the limit is reached and the download fails with a 429. Here's a log snippet that includes several of the last successful downloads on the 19th, and a couple of the unsuccessful attempts that follow.

Log snippet from April 19th, including failed (429) download attempts
shlink  | 2024-04-19T12:21:00+0000	INFO	server      	[2024-04-19T12:21:00.368513+00:00] [f84d96b7-1572-46f0-9315-c24234990580] Access.INFO - GET /atom.xml 302 0
shlink  | 2024-04-19T12:21:01+0000	DEBUG	jobs        	job was processed successfully	{"ID": "2bd84ce2-3963-4c0d-94f4-1b8d5a36ce02", "start": "2024-04-19T12:20:57+0000", "elapsed": 3418}
shlink  | 2024-04-19T12:21:02+0000	DEBUG	jobs        	job was pushed successfully	{"ID": "30fec458-4c90-491d-845f-3edea83eefed", "pipeline": "shlink", "driver": "memory", "start": "2024-04-19T12:21:02+0000", "elapsed": 0}
shlink  | {"level":"debug","ts":1713529262023799186,"logger":"memory","msg":"message pushed to the priority queue","current":1,"limit":10}
shlink  | 2024-04-19T12:21:02+0000	DEBUG	jobs        	job processing was started	{"ID": "30fec458-4c90-491d-845f-3edea83eefed", "start": "2024-04-19T12:20:58+0000", "elapsed": 3239}
shlink  | 2024-04-19T12:21:02+0000	INFO	server      	[2024-04-19T12:21:02.027296+00:00] [-] Shlink.NOTICE - Updating GeoLite2 db file...
shlink  | 
shlink  | 2024-04-19T12:21:02+0000	INFO	server      	[2024-04-19T12:21:02.028673+00:00] [-] Shlink.NOTICE - Finished updating GeoLite2 db file
shlink  | 
shlink  | 2024-04-19T12:21:02+0000	INFO	server      	[2024-04-19T12:21:02.042746+00:00] [1766b791-1a6e-4901-bf4a-ee0f0a1bdf80] Access.INFO - GET /poll-results-ioc-containers-for-net 302 0
shlink  | 2024-04-19T12:21:03+0000	DEBUG	jobs        	job was processed successfully	{"ID": "30fec458-4c90-491d-845f-3edea83eefed", "start": "2024-04-19T12:20:58+0000", "elapsed": 4382}
shlink  | 2024-04-19T12:21:04+0000	DEBUG	jobs        	job was pushed successfully	{"ID": "a449a7a0-2e5d-4665-94c0-71786f317cea", "pipeline": "shlink", "driver": "memory", "start": "2024-04-19T12:21:04+0000", "elapsed": 0}
shlink  | {"level":"debug","ts":1713529264111831067,"logger":"memory","msg":"message pushed to the priority queue","current":1,"limit":10}
shlink  | 2024-04-19T12:21:04+0000	DEBUG	jobs        	job processing was started	{"ID": "a449a7a0-2e5d-4665-94c0-71786f317cea", "start": "2024-04-19T12:21:00+0000", "elapsed": 3872}
shlink  | 2024-04-19T12:21:04+0000	INFO	server      	[2024-04-19T12:21:04.113562+00:00] [-] Shlink.NOTICE - Updating GeoLite2 db file...
shlink  | 
shlink  | 2024-04-19T12:21:04+0000	INFO	server      	[2024-04-19T12:21:04.114824+00:00] [-] Shlink.NOTICE - Finished updating GeoLite2 db file
shlink  | 
shlink  | 2024-04-19T12:21:04+0000	INFO	server      	[2024-04-19T12:21:04.122305+00:00] [c22465d6-cfd4-478b-a562-8203875d1594] Access.INFO - GET /cr-electric-editing 302 0
shlink  | 2024-04-19T12:21:05+0000	DEBUG	jobs        	job was processed successfully	{"ID": "a449a7a0-2e5d-4665-94c0-71786f317cea", "start": "2024-04-19T12:21:00+0000", "elapsed": 4901}
shlink  | 2024-04-19T12:21:05+0000	DEBUG	jobs        	job was pushed successfully	{"ID": "c2245c8b-e751-455b-9546-bb9574f3bf0e", "pipeline": "shlink", "driver": "memory", "start": "2024-04-19T12:21:05+0000", "elapsed": 0}
shlink  | {"level":"debug","ts":1713529265531374829,"logger":"memory","msg":"message pushed to the priority queue","current":1,"limit":10}
shlink  | 2024-04-19T12:21:05+0000	DEBUG	jobs        	job processing was started	{"ID": "c2245c8b-e751-455b-9546-bb9574f3bf0e", "start": "2024-04-19T12:21:01+0000", "elapsed": 4346}
shlink  | 2024-04-19T12:21:05+0000	INFO	server      	[2024-04-19T12:21:05.533188+00:00] [-] Shlink.NOTICE - Updating GeoLite2 db file...
shlink  | [2024-04-19T12:21:05.533748+00:00] [-] Shlink.NOTICE - Finished updating GeoLite2 db file
shlink  | 
shlink  | 2024-04-19T12:21:05+0000	INFO	server      	[2024-04-19T12:21:05.545712+00:00] [0432bfd3-7cdf-46f7-b0eb-055e5f3daebb] Access.INFO - GET /terms 302 0
shlink  | 2024-04-19T12:21:06+0000	DEBUG	jobs        	job was processed successfully	{"ID": "c2245c8b-e751-455b-9546-bb9574f3bf0e", "start": "2024-04-19T12:21:01+0000", "elapsed": 5126}
shlink  | 2024-04-19T12:21:06+0000	DEBUG	jobs        	job was pushed successfully	{"ID": "42db8616-192b-4304-b263-16bb08827215", "pipeline": "shlink", "driver": "memory", "start": "2024-04-19T12:21:06+0000", "elapsed": 2}
shlink  | {"level":"debug","ts":1713529266988114878,"logger":"memory","msg":"message pushed to the priority queue","current":1,"limit":10}
shlink  | 2024-04-19T12:21:06+0000	DEBUG	jobs        	job processing was started	{"ID": "42db8616-192b-4304-b263-16bb08827215", "start": "2024-04-19T12:21:03+0000", "elapsed": 3820}
shlink  | 2024-04-19T12:21:06+0000	INFO	server      	[2024-04-19T12:21:06.993074+00:00] [-] Shlink.NOTICE - Updating GeoLite2 db file...
shlink  | 
shlink  | 2024-04-19T12:21:06+0000	INFO	server      	[2024-04-19T12:21:06.998310+00:00] [-] Shlink.NOTICE - Finished updating GeoLite2 db file
shlink  | 
shlink  | 2024-04-19T12:21:07+0000	INFO	server      	[2024-04-19T12:21:07.005719+00:00] [82b551e3-f79b-44ba-9818-35b53f54a541] Access.INFO - GET /tags/Linux/1 302 0
shlink  | 2024-04-19T12:21:08+0000	DEBUG	jobs        	job was processed successfully	{"ID": "42db8616-192b-4304-b263-16bb08827215", "start": "2024-04-19T12:21:03+0000", "elapsed": 4886}
shlink  | 2024-04-19T12:21:09+0000	DEBUG	jobs        	job was pushed successfully	{"ID": "a1262ef7-3ba6-4f24-997b-b428836853f9", "pipeline": "shlink", "driver": "memory", "start": "2024-04-19T12:21:09+0000", "elapsed": 0}
shlink  | {"level":"debug","ts":1713529269184735926,"logger":"memory","msg":"message pushed to the priority queue","current":1,"limit":10}
shlink  | 2024-04-19T12:21:09+0000	DEBUG	jobs        	job processing was started	{"ID": "a1262ef7-3ba6-4f24-997b-b428836853f9", "start": "2024-04-19T12:21:05+0000", "elapsed": 4042}
shlink  | 2024-04-19T12:21:09+0000	INFO	server      	[2024-04-19T12:21:09.187120+00:00] [-] Shlink.NOTICE - Updating GeoLite2 db file...
shlink  | 
shlink  | 2024-04-19T12:21:09+0000	INFO	server      	[2024-04-19T12:21:09.188482+00:00] [-] Shlink.NOTICE - Finished updating GeoLite2 db file
shlink  | 
shlink  | 2024-04-19T12:21:09+0000	INFO	server      	[2024-04-19T12:21:09.192686+00:00] [9996650e-dfcd-4f1b-8855-cf4550c20a20] Access.INFO - GET /tags/Training/1 302 0
shlink  | 2024-04-19T12:21:10+0000	DEBUG	jobs        	job was processed successfully	{"ID": "a1262ef7-3ba6-4f24-997b-b428836853f9", "start": "2024-04-19T12:21:05+0000", "elapsed": 5053}
shlink  | 2024-04-19T12:21:11+0000	DEBUG	jobs        	job was pushed successfully	{"ID": "c24efeb7-afe5-45de-89d4-2c1a4d5ca0ca", "pipeline": "shlink", "driver": "memory", "start": "2024-04-19T12:21:11+0000", "elapsed": 0}
shlink  | {"level":"debug","ts":1713529271531053096,"logger":"memory","msg":"message pushed to the priority queue","current":1,"limit":10}
shlink  | 2024-04-19T12:21:11+0000	DEBUG	jobs        	job processing was started	{"ID": "c24efeb7-afe5-45de-89d4-2c1a4d5ca0ca", "start": "2024-04-19T12:21:06+0000", "elapsed": 5218}
shlink  | 2024-04-19T12:21:11+0000	INFO	server      	[2024-04-19T12:21:11.533307+00:00] [-] Shlink.NOTICE - Updating GeoLite2 db file...
shlink  | 
shlink  | 2024-04-19T12:21:11+0000	INFO	server      	[2024-04-19T12:21:11.534912+00:00] [-] Shlink.NOTICE - Finished updating GeoLite2 db file
shlink  | 
shlink  | 2024-04-19T12:21:11+0000	INFO	server      	[2024-04-19T12:21:11.545803+00:00] [3497029a-e192-4ca8-a74f-a6b41b75a007] Access.INFO - GET /tags/C%23/1 302 0
shlink  | 2024-04-19T12:21:12+0000	DEBUG	jobs        	job was processed successfully	{"ID": "c24efeb7-afe5-45de-89d4-2c1a4d5ca0ca", "start": "2024-04-19T12:21:06+0000", "elapsed": 6128}
shlink  | 2024-04-19T12:21:13+0000	DEBUG	jobs        	job was pushed successfully	{"ID": "10c1c7c8-565f-4f24-8ff4-f36aef2d3452", "pipeline": "shlink", "driver": "memory", "start": "2024-04-19T12:21:13+0000", "elapsed": 0}
shlink  | {"level":"debug","ts":1713529273967244284,"logger":"memory","msg":"message pushed to the priority queue","current":1,"limit":10}
shlink  | 2024-04-19T12:21:13+0000	DEBUG	jobs        	job processing was started	{"ID": "10c1c7c8-565f-4f24-8ff4-f36aef2d3452", "start": "2024-04-19T12:21:08+0000", "elapsed": 5912}
shlink  | 2024-04-19T12:21:13+0000	INFO	server      	[2024-04-19T12:21:13.970678+00:00] [-] Shlink.NOTICE - Updating GeoLite2 db file...
shlink  | 
shlink  | 2024-04-19T12:21:13+0000	INFO	server      	[2024-04-19T12:21:13.972251+00:00] [-] Shlink.NOTICE - Finished updating GeoLite2 db file
shlink  | 
shlink  | 2024-04-19T12:21:13+0000	INFO	server      	[2024-04-19T12:21:13.979135+00:00] [bb232958-c93d-4ac1-a7b7-dbd475a272fe] Access.INFO - GET /tags/Programming/1 302 0
shlink  | 2024-04-19T12:21:14+0000	INFO	server      	[2024-04-19T12:21:14.119526+00:00] [-] Shlink.ERROR - GeoLite2 database download failed. 
shlink  | GuzzleHttp\Exception\ClientException: Client error: `GET https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=Jly2oT5duCMu8OGr&suffix=tar.gz` resulted in a `429 Too Many Requests` response:
shlink  | Daily GeoIP database download limit reached
shlink  | 
shlink  |  in /etc/shlink/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:113
shlink  | Stack trace:
shlink  | #0 /etc/shlink/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\Exception\RequestException::create(Object(GuzzleHttp\Psr7\Request), Object(GuzzleHttp\Psr7\Response), NULL, Array, NULL)
shlink  | #1 /etc/shlink/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Response))
shlink  | #2 /etc/shlink/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\Promise\Promise::callHandler(1, Object(GuzzleHttp\Psr7\Response), NULL)
shlink  | #3 /etc/shlink/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\{closure}()
shlink  | #4 /etc/shlink/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\Promise\TaskQueue->run(true)
shlink  | #5 /etc/shlink/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\Promise\Promise->invokeWaitFn()
shlink  | #6 /etc/shlink/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\Promise\Promise->waitIfPending()
shlink  | #7 /etc/shlink/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\Promise\Promise->invokeWaitList()
shlink  | #8 /etc/shlink/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\Promise\Promise->waitIfPending()
shlink  | #9 /etc/shlink/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\Promise\Promise->wait()
shlink  | #10 /etc/shlink/vendor/shlinkio/shlink-ip-geolocation/src/GeoLite2/DbUpdater.php(57): GuzzleHttp\Client->request('GET', 'https://downloa...', Array)
shlink  | #11 /etc/shlink/vendor/shlinkio/shlink-ip-geolocation/src/GeoLite2/DbUpdater.php(45): Shlinkio\Shlink\IpGeolocation\GeoLite2\DbUpdater->downloadDbFile('/etc/shlink/con...', Object(Closure))
shlink  | #12 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(116): Shlinkio\Shlink\IpGeolocation\GeoLite2\DbUpdater->downloadFreshCopy(Object(Closure))
shlink  | #13 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(70): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->downloadNewDb(true, Object(Closure), Object(Closure))
shlink  | #14 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(53): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->downloadIfNeeded(Object(Closure), Object(Closure))
shlink  | #15 /etc/shlink/module/Core/src/EventDispatcher/UpdateGeoLiteDb.php(41): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->checkDbUpdate(Object(Closure), Object(Closure))
shlink  | #16 /etc/shlink/vendor/shlinkio/shlink-event-dispatcher/src/RoadRunner/RoadRunnerTaskConsumerToListener.php(41): Shlinkio\Shlink\Core\EventDispatcher\UpdateGeoLiteDb->__invoke(Object(Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated))
shlink  | #17 /etc/shlink/bin/roadrunner-worker.php(30): Shlinkio\Shlink\EventDispatcher\RoadRunner\RoadRunnerTaskConsumerToListener->listenForTasks()
shlink  | #18 /etc/shlink/bin/roadrunner-worker.php(32): {closure}()
shlink  | #19 {main}
shlink  | 
shlink  | Next Shlinkio\Shlink\IpGeolocation\Exception\DbUpdateException: An error occurred while trying to download a fresh copy of the GeoLite2 database in /etc/shlink/vendor/shlinkio/shlink-ip-geolocation/src/Exception/DbUpdateException.php:36
shlink  | Stack trace:
shlink  | #0 /etc/shlink/vendor/shlinkio/shlink-ip-geolocation/src/Exception/DbUpdateException.php(15): Shlinkio\Shlink\IpGeolocation\Exception\DbUpdateException::build('An error occurr...', Object(GuzzleHttp\Exception\ClientException))
shlink  | #1 /etc/shlink/vendor/shlinkio/shlink-ip-geolocation/src/GeoLite2/DbUpdater.php(63): Shlinkio\Shlink\IpGeolocation\Exception\DbUpdateException::forFailedDownload(Object(GuzzleHttp\Exception\ClientException))
shlink  | #2 /etc/shlink/vendor/shlinkio/shlink-ip-geolocation/src/GeoLite2/DbUpdater.php(45): Shlinkio\Shlink\IpGeolocation\GeoLite2\DbUpdater->downloadDbFile('/etc/shlink/con...', Object(Closure))
shlink  | #3 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(116): Shlinkio\Shlink\IpGeolocation\GeoLite2\DbUpdater->downloadFreshCopy(Object(Closure))
shlink  | #4 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(70): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->downloadNewDb(true, Object(Closure), Object(Closure))
shlink  | #5 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(53): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->downloadIfNeeded(Object(Closure), Object(Closure))
shlink  | #6 /etc/shlink/module/Core/src/EventDispatcher/UpdateGeoLiteDb.php(41): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->checkDbUpdate(Object(Closure), Object(Closure))
shlink  | #7 /etc/shlink/vendor/shlinkio/shlink-event-dispatcher/src/RoadRunner/RoadRunnerTaskConsumerToListener.php(41): Shlinkio\Shlink\Core\EventDispatcher\UpdateGeoLiteDb->__invoke(Object(Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated))
shlink  | #8 /etc/shlink/bin/roadrunner-worker.php(30): Shlinkio\Shlink\EventDispatcher\RoadRunner\RoadRunnerTaskConsumerToListener->listenForTasks()
shlink  | #9 /etc/shlink/bin/roadrunner-worker.php(32): {closure}()
shlink  | #10 {main}
shlink  | 
shlink  | Next Shlinkio\Shlink\CLI\Exception\GeolocationDbUpdateFailedException: An error occurred while updating geolocation database, but an older DB is already present. in /etc/shlink/module/CLI/src/Exception/GeolocationDbUpdateFailedException.php:23
shlink  | Stack trace:
shlink  | #0 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(122): Shlinkio\Shlink\CLI\Exception\GeolocationDbUpdateFailedException::withOlderDb(Object(Shlinkio\Shlink\IpGeolocation\Exception\DbUpdateException))
shlink  | #1 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(70): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->downloadNewDb(true, Object(Closure), Object(Closure))
shlink  | #2 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(53): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->downloadIfNeeded(Object(Closure), Object(Closure))
shlink  | #3 /etc/shlink/module/Core/src/EventDispatcher/UpdateGeoLiteDb.php(41): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->checkDbUpdate(Object(Closure), Object(Closure))
shlink  | #4 /etc/shlink/vendor/shlinkio/shlink-event-dispatcher/src/RoadRunner/RoadRunnerTaskConsumerToListener.php(41): Shlinkio\Shlink\Core\EventDispatcher\UpdateGeoLiteDb->__invoke(Object(Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated))
shlink  | #5 /etc/shlink/bin/roadrunner-worker.php(30): Shlinkio\Shlink\EventDispatcher\RoadRunner\RoadRunnerTaskConsumerToListener->listenForTasks()
shlink  | #6 /etc/shlink/bin/roadrunner-worker.php(32): {closure}()
shlink  | #7 {main}
shlink  | 
shlink  | 2024-04-19T12:21:14+0000	DEBUG	jobs        	job was processed successfully	{"ID": "10c1c7c8-565f-4f24-8ff4-f36aef2d3452", "start": "2024-04-19T12:21:08+0000", "elapsed": 6072}
shlink  | 2024-04-19T12:21:14+0000	DEBUG	jobs        	job was pushed successfully	{"ID": "e7a0eb15-01db-44c1-940b-3051531d4875", "pipeline": "shlink", "driver": "memory", "start": "2024-04-19T12:21:14+0000", "elapsed": 0}
shlink  | {"level":"debug","ts":1713529274965454970,"logger":"memory","msg":"message pushed to the priority queue","current":1,"limit":10}
shlink  | 2024-04-19T12:21:14+0000	DEBUG	jobs        	job processing was started	{"ID": "e7a0eb15-01db-44c1-940b-3051531d4875", "start": "2024-04-19T12:21:10+0000", "elapsed": 4769}
shlink  | 2024-04-19T12:21:14+0000	INFO	server      	[2024-04-19T12:21:14.967610+00:00] [-] Shlink.NOTICE - Updating GeoLite2 db file...
shlink  | [2024-04-19T12:21:14.968189+00:00] [-] Shlink.NOTICE - Finished updating GeoLite2 db file
shlink  | 
shlink  | 2024-04-19T12:21:14+0000	INFO	server      	[2024-04-19T12:21:14.973282+00:00] [c0d634b9-2c6c-4dd8-aae1-803e00d47f1c] Access.INFO - GET /tags/Software/1 302 0
shlink  | 2024-04-19T12:21:15+0000	DEBUG	jobs        	job was processed successfully	{"ID": "e7a0eb15-01db-44c1-940b-3051531d4875", "start": "2024-04-19T12:21:10+0000", "elapsed": 4884}
shlink  | 2024-04-19T12:21:15+0000	INFO	server      	[2024-04-19T12:21:15.080003+00:00] [-] Shlink.ERROR - GeoLite2 database download failed. 
shlink  | GuzzleHttp\Exception\ClientException: Client error: `GET https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=Jly2oT5duCMu8OGr&suffix=tar.gz` resulted in a `429 Too Many Requests` response:
shlink  | Daily GeoIP database download limit reached
shlink  | 
shlink  |  in /etc/shlink/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:113
shlink  | Stack trace:
shlink  | #0 /etc/shlink/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\Exception\RequestException::create(Object(GuzzleHttp\Psr7\Request), Object(GuzzleHttp\Psr7\Response), NULL, Array, NULL)
shlink  | #1 /etc/shlink/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Response))
shlink  | #2 /etc/shlink/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\Promise\Promise::callHandler(1, Object(GuzzleHttp\Psr7\Response), NULL)
shlink  | #3 /etc/shlink/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\{closure}()
shlink  | #4 /etc/shlink/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\Promise\TaskQueue->run(true)
shlink  | #5 /etc/shlink/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\Promise\Promise->invokeWaitFn()
shlink  | #6 /etc/shlink/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\Promise\Promise->waitIfPending()
shlink  | #7 /etc/shlink/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\Promise\Promise->invokeWaitList()
shlink  | #8 /etc/shlink/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\Promise\Promise->waitIfPending()
shlink  | #9 /etc/shlink/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\Promise\Promise->wait()
shlink  | #10 /etc/shlink/vendor/shlinkio/shlink-ip-geolocation/src/GeoLite2/DbUpdater.php(57): GuzzleHttp\Client->request('GET', 'https://downloa...', Array)
shlink  | #11 /etc/shlink/vendor/shlinkio/shlink-ip-geolocation/src/GeoLite2/DbUpdater.php(45): Shlinkio\Shlink\IpGeolocation\GeoLite2\DbUpdater->downloadDbFile('/etc/shlink/con...', Object(Closure))
shlink  | #12 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(116): Shlinkio\Shlink\IpGeolocation\GeoLite2\DbUpdater->downloadFreshCopy(Object(Closure))
shlink  | #13 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(70): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->downloadNewDb(true, Object(Closure), Object(Closure))
shlink  | #14 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(53): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->downloadIfNeeded(Object(Closure), Object(Closure))
shlink  | #15 /etc/shlink/module/Core/src/EventDispatcher/UpdateGeoLiteDb.php(41): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->checkDbUpdate(Object(Closure), Object(Closure))
shlink  | #16 /etc/shlink/vendor/shlinkio/shlink-event-dispatcher/src/RoadRunner/RoadRunnerTaskConsumerToListener.php(41): Shlinkio\Shlink\Core\EventDispatcher\UpdateGeoLiteDb->__invoke(Object(Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated))
shlink  | #17 /etc/shlink/bin/roadrunner-worker.php(30): Shlinkio\Shlink\EventDispatcher\RoadRunner\RoadRunnerTaskConsumerToListener->listenForTasks()
shlink  | #18 /etc/shlink/bin/roadrunner-worker.php(32): {closure}()
shlink  | #19 {main}
shlink  | 
shlink  | Next Shlinkio\Shlink\IpGeolocation\Exception\DbUpdateException: An error occurred while trying to download a fresh copy of the GeoLite2 database in /etc/shlink/vendor/shlinkio/shlink-ip-geolocation/src/Exception/DbUpdateException.php:36
shlink  | Stack trace:
shlink  | #0 /etc/shlink/vendor/shlinkio/shlink-ip-geolocation/src/Exception/DbUpdateException.php(15): Shlinkio\Shlink\IpGeolocation\Exception\DbUpdateException::build('An error occurr...', Object(GuzzleHttp\Exception\ClientException))
shlink  | #1 /etc/shlink/vendor/shlinkio/shlink-ip-geolocation/src/GeoLite2/DbUpdater.php(63): Shlinkio\Shlink\IpGeolocation\Exception\DbUpdateException::forFailedDownload(Object(GuzzleHttp\Exception\ClientException))
shlink  | #2 /etc/shlink/vendor/shlinkio/shlink-ip-geolocation/src/GeoLite2/DbUpdater.php(45): Shlinkio\Shlink\IpGeolocation\GeoLite2\DbUpdater->downloadDbFile('/etc/shlink/con...', Object(Closure))
shlink  | #3 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(116): Shlinkio\Shlink\IpGeolocation\GeoLite2\DbUpdater->downloadFreshCopy(Object(Closure))
shlink  | #4 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(70): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->downloadNewDb(true, Object(Closure), Object(Closure))
shlink  | #5 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(53): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->downloadIfNeeded(Object(Closure), Object(Closure))
shlink  | #6 /etc/shlink/module/Core/src/EventDispatcher/UpdateGeoLiteDb.php(41): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->checkDbUpdate(Object(Closure), Object(Closure))
shlink  | #7 /etc/shlink/vendor/shlinkio/shlink-event-dispatcher/src/RoadRunner/RoadRunnerTaskConsumerToListener.php(41): Shlinkio\Shlink\Core\EventDispatcher\UpdateGeoLiteDb->__invoke(Object(Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated))
shlink  | #8 /etc/shlink/bin/roadrunner-worker.php(30): Shlinkio\Shlink\EventDispatcher\RoadRunner\RoadRunnerTaskConsumerToListener->listenForTasks()
shlink  | #9 /etc/shlink/bin/roadrunner-worker.php(32): {closure}()
shlink  | #10 {main}
shlink  | 
shlink  | Next Shlinkio\Shlink\CLI\Exception\GeolocationDbUpdateFailedException: An error occurred while updating geolocation database, but an older DB is already present. in /etc/shlink/module/CLI/src/Exception/GeolocationDbUpdateFailedException.php:23
shlink  | Stack trace:
shlink  | #0 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(122): Shlinkio\Shlink\CLI\Exception\GeolocationDbUpdateFailedException::withOlderDb(Object(Shlinkio\Shlink\IpGeolocation\Exception\DbUpdateException))
shlink  | #1 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(70): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->downloadNewDb(true, Object(Closure), Object(Closure))
shlink  | #2 /etc/shlink/module/CLI/src/GeoLite/GeolocationDbUpdater.php(53): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->downloadIfNeeded(Object(Closure), Object(Closure))
shlink  | #3 /etc/shlink/module/Core/src/EventDispatcher/UpdateGeoLiteDb.php(41): Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater->checkDbUpdate(Object(Closure), Object(Closure))
shlink  | #4 /etc/shlink/vendor/shlinkio/shlink-event-dispatcher/src/RoadRunner/RoadRunnerTaskConsumerToListener.php(41): Shlinkio\Shlink\Core\EventDispatcher\UpdateGeoLiteDb->__invoke(Object(Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated))
shlink  | #5 /etc/shlink/bin/roadrunner-worker.php(30): Shlinkio\Shlink\EventDispatcher\RoadRunner\RoadRunnerTaskConsumerToListener->listenForTasks()
shlink  | #6 /etc/shlink/bin/roadrunner-worker.php(32): {closure}()
shlink  | #7 {main}
shlink  | 
shlink  | 2024-04-19T12:21:17+0000	DEBUG	jobs        	job was pushed successfully	{"ID": "d60d3472-ace6-4af4-88bb-38b945c03be9", "pipeline": "shlink", "driver": "memory", "start": "2024-04-19T12:21:17+0000", "elapsed": 0}
shlink  | {"level":"debug","ts":1713529277156259100,"logger":"memory","msg":"message pushed to the priority queue","current":1,"limit":10}
shlink  | 2024-04-19T12:21:17+0000	DEBUG	jobs        	job processing was started	{"ID": "d60d3472-ace6-4af4-88bb-38b945c03be9", "start": "2024-04-19T12:21:12+0000", "elapsed": 4714}
shlink  | 2024-04-19T12:21:17+0000	INFO	server      	[2024-04-19T12:21:17.158275+00:00] [-] Shlink.NOTICE - Updating GeoLite2 db file...
...

The attempts continue after that, I see 76 of them on the 19th:

> grep -e '2024-04-19.*database download failed' 20240429-shlink.log | wc -l
      76

Please let me know how else I can help figure this out.

@acelaya
Copy link
Member

acelaya commented May 2, 2024

Thanks for the detailed information.

For context, this is how Shlink handles GeoLite downloads:

When the first visit reaches an instance, Shlink detects the file does not exist and tries to download it for the first time, logging the message "Finished downloading GeoLite2 db file".

In the context of docker, "the first time" means it's a new container, which can happen for a number of reasons: autoscaling, the service was updated to a new version, etc. Every container will need to download its own GeoLite2 db file.

If the file exists, Shlink will check if it needs to be updated based on its own metadata, by verifying if it's older than 35 days. This would explain your comment: "Perhaps not a coincidence that there's close to one month in between?"

After those 35 days, Shlink will download the newest available version and log "Finished updating GeoLite2 db file".

The problem originally reported in #2021, happened because once the first file was downloaded, Shlink kept a reference to its metadata in memory, causing all checks to result in a download once a container run for more than 35 days.

Both that problem and probably this one, would be mitigated by regenerating new containers, which is probably what makes this happen less often.

That said, I'm taking a few days off, but I'll try to debug a bit further as soon as I can.

@oliversturm
Copy link
Author

The problem originally reported in #2021, happened because once the first file was downloaded, Shlink kept a reference to its metadata in memory, causing all checks to result in a download once a container run for more than 35 days.

Right. It looks to me as if this is still happening here. Perhaps it would be possible to add some information to the log output that would allow us to understand the decision making process. I.e. something like deciding to download GeoLite database because last download on XXX is YYY days ago... or whatever other details come into it.

@oliversturm
Copy link
Author

Update. I added debug output to see the $buildDate variable at this point. I see that in my running container it has this value (formatted as an ISO string): 2024-03-12T14:30:24+00:00

Clearly this is very outdated. Now perhaps I'll track down why the meta data has not been updated after any of the successful downloads that clearly happened.

@oliversturm
Copy link
Author

I don't think I know PHP well enough. I see that a new Reader is created for each call to the factory here. As a result I would think that the new file should be used, once it has been copied to the path in options->dbLocation, which doesn't seem to change.

And before the metadata is extracted, the factory is called, here. Clearly we're still looking at outdated metadata, but I'm not sure why... unless the new Reader instance returns it for some reason.

@acelaya
Copy link
Member

acelaya commented May 3, 2024

Perhaps it would be possible to add some information to the log output that would allow us to understand the decision making process. I.e. something like deciding to download GeoLite database because last download on XXX is YYY days ago... or whatever other details come into it

Yep, good idea.

Clearly we're still looking at outdated metadata, but I'm not sure why... unless the new Reader instance returns it for some reason.

This is the direction in which my thinking is going, but I'm also a bit clueless why this happened.

It happened a few years ago, that a new GeoLite file was published with incorrect metadata, but I don't think this is very likely to happen.

I'll need to debug a bit further, but thanks for giving it a try, that was really helpful.

@acelaya
Copy link
Member

acelaya commented May 4, 2024

I'm not being able to reproduce this with latest Shlink. I have tried downloading an older version of the GeoLite2 db file, starting Shlink, visiting a short URL.

Shlink detects the file is too old, and starts downloading a newer version.

Once finished, if I visit a new short URL, Shlink properly checks the new file is up to date, and does not try to download again.

I have also tried visits in parallel. Thanks to the lock, one of them downloads the GeoLite file, then the lock is released, and by the time the rest are checked, they do it against the new file.

@acelaya
Copy link
Member

acelaya commented May 4, 2024

I have just also done some testing with Shlink 4.0.1 and 4.0.2

With the first one, if I replace the database with a very old version, any visit continues to consider the database is up to date, because of the references in memory.

With v4.0.2 though, they always pick the version is old, download a new one, and following requests work as expected with the new db file.

Could it be that you had some orphan or old Shlink containers running in a version older than 4.0.2, which were the ones producing this issue?

@oliversturm
Copy link
Author

Sorry, forgot to follow up here.

Could it be that you had some orphan or old Shlink containers running in a version older than 4.0.2, which were the ones producing this issue?

No. There was just the one container that identified itself as version 4.0.2. It was still running when we last wrote, and it is still active now, albeit with a small change to the source code that outputs a debug message for the build date read from the metadata.

And that's where an interesting thing happened recently. I had a screen session open that was following the log file after our recent tests. And when I looked at that open session again, I found this:

> docker compose logs -f shlink | grep "Meta build"
shlink  | 2024-05-03T10:54:57+0000      INFO    server          [2024-05-03T10:54:57.374148+00:00] [-] Shlink.NOTICE - Meta build date is 2024-03-12T14:30:24+00:00
shlink  | 2024-05-03T12:22:13+0000      INFO    server          [2024-05-03T12:22:13.495630+00:00] [-] Shlink.NOTICE - Meta build date is 2024-03-12T14:30:24+00:00
shlink  | 2024-05-03T13:22:11+0000      INFO    server          [2024-05-03T13:22:11.708647+00:00] [-] Shlink.NOTICE - Meta build date is 2024-03-12T14:30:24+00:00
shlink  | 2024-05-03T13:22:23+0000      INFO    server          [2024-05-03T13:22:23.467587+00:00] [-] Shlink.NOTICE - Meta build date is 2024-03-12T14:30:24+00:00
shlink  | 2024-05-03T13:22:26+0000      INFO    server          [2024-05-03T13:22:26.821597+00:00] [-] Shlink.NOTICE - Meta build date is 2024-03-12T14:30:24+00:00
shlink  | 2024-05-03T13:22:33+0000      INFO    server          [2024-05-03T13:22:33.285331+00:00] [-] Shlink.NOTICE - Meta build date is 2024-03-12T14:30:24+00:00
shlink  | 2024-05-03T15:26:18+0000      INFO    server          [2024-05-03T15:26:18.569636+00:00] [-] Shlink.NOTICE - Meta build date is 2024-03-12T14:30:24+00:00
shlink  | 2024-05-03T15:29:42+0000      INFO    server          [2024-05-03T15:29:42.649483+00:00] [-] Shlink.NOTICE - Meta build date is 2024-03-12T14:30:24+00:00
shlink  | 2024-05-03T15:49:48+0000      INFO    server          [2024-05-03T15:49:48.798808+00:00] [-] Shlink.NOTICE - Meta build date is 2024-03-12T14:30:24+00:00
shlink  | 2024-05-03T15:49:49+0000      INFO    server          [2024-05-03T15:49:49.377408+00:00] [-] Shlink.NOTICE - Meta build date is 2024-03-12T14:30:24+00:00
shlink  | 2024-05-03T15:49:49+0000      INFO    server          [2024-05-03T15:49:49.774814+00:00] [-] Shlink.NOTICE - Meta build date is 2024-03-12T14:30:24+00:00
shlink  | 2024-05-03T19:43:05+0000      INFO    server          [2024-05-03T19:43:05.519738+00:00] [-] Shlink.NOTICE - Meta build date is 2024-03-12T14:30:24+00:00
shlink  | 2024-05-03T21:10:21+0000      INFO    server          [2024-05-03T21:10:21.658584+00:00] [-] Shlink.NOTICE - Meta build date is 2024-03-12T14:30:24+00:00
shlink  | 2024-05-04T00:07:58+0000      INFO    server          [2024-05-04T00:07:58.281199+00:00] [-] Shlink.NOTICE - Meta build date is 2024-03-12T14:30:24+00:00
shlink  | 2024-05-04T03:12:31+0000      INFO    server          [2024-05-04T03:12:31.709732+00:00] [-] Shlink.NOTICE - Meta build date is 2024-03-12T14:30:24+00:00
shlink  | 2024-05-04T03:38:40+0000      INFO    server          [2024-05-04T03:38:40.165622+00:00] [-] Shlink.NOTICE - Meta build date is 2024-05-03T12:43:40+00:00
...

To summarize, the log output shows that after I added the debug output, there were 15 further occasions on May 3rd and May 4th where the build date was checked -- and each time it was found to be the same "old" date back in March.
Then suddenly, a new build date comes up! I cut off the rest of the log output -- there are 65 additional lines that show the same build date as the last line in the snippet above.

It appears that my system actually had an old metadata timestamp the whole time, resulting in countless downloads. Then at some point it received a download where the metadata was finally updated correctly. Why? Not a clue...

@acelaya
Copy link
Member

acelaya commented May 8, 2024

The only reason I can think of is that there were no actual successful downloads at all. Eventually, because of the API limits, but perhaps the first daily attempts did not succeed either.

If you look for GeoLite2 database download failed. in the logs, does any of them log an exception trace which is different than the 429 status response?

Maybe Shlink did in fact start downloading the file on the first 30 attempts every day, but then the download timed out, it was not able to write the temp file or extract it, etc.

Another reason, as I mentioned somewhere above, is that Shlink downloaded files with incorrect metadata, but this is something hard to verify. I'll try to download some of the latest DBs ate check them.

Another useful thing to check is if Shlink logged any successful download. Can you find any appearance of Finished updating GeoLite2 db file or Finished downloading GeoLite2 db file in the logs for any of the days where there are errors?

@oliversturm
Copy link
Author

Yes, check my previous reports. There were many apparently successful downloads on all days, including the days where 429 errors were displayed later on. I have not found any errors that had a different exception than the 429 one.

It seems to me that it may be best at this point for me to rebuild the container on the latest state and leave it to run, in order to see whether the problem returns in the future. The evidence is there that something was odd with the metadata in my running container, and that this problem somehow went away after lots of occurrences, but I'm not sure there's anything more to learn in hindsight.

@acelaya
Copy link
Member

acelaya commented May 8, 2024

Thanks for your help debugging this.

In any case, what's becoming more clear to me is that this approach to trigger GeoLite2 downloads is too brittle.

In an ideal world, Shlink would try to download the GeoLite2 db as soon as possible when it does not exist yet, then try to update it every N days, and schedule more attempts in case of error, after a few hours/days, with a maximum amount of attempts per day.

The problem is that technologies used by Shlink do not natively allow that kind of scheduling, so the way I thought I could mimic that would be by running a job after every visit, and check if those conditions are met based on date calculations. It seemed convenient, and requires no interaction from the user, but it can lead to too many attempts if certain errors occur, which can make things even worst as soon as API limits are reached.

In the past, updating the GeoLite2 db was done via cronjobs, but that required manual interactions from users, and it's not very convenient in docker contexts. It is still the recommended approach for people not using RoadRunner https://shlink.io/documentation/long-running-tasks/#download-geolite2-db

I'll try to put some time checking if there's a better way to do this.

@acelaya
Copy link
Member

acelaya commented May 10, 2024

I have created #2124 in order to implement some improvements in the download approach.

I'll close this for now.

@acelaya acelaya closed this as completed May 10, 2024
@github-project-automation github-project-automation bot moved this to Done in Shlink May 10, 2024
@acelaya acelaya removed the status in Shlink May 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: No status
Development

No branches or pull requests

2 participants