Poll-Takt von 15 Minuten auf 2 Stunden senken
Reduziert den Traffic gegen die Quellen. slot_von() rundet jetzt generisch auf TAKT-Grenzen statt fest auf 15-Minuten-Slots, die Stillstands-Schwelle in quellen_stillstand steigt von 6h auf 24h, damit der Watchdog nicht schon nach drei verpassten Slots anschlaegt. GDELT-Vergleich aus den Kommentaren entfernt, da die Slots nicht mehr mit dessen 15-Minuten-Paketen zusammenfallen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013vHZCwcCJnz4LKNgvT4bxv
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
c43d8496bf
commit
8a1ab8a146
@@ -0,0 +1,2 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
+1
-1
@@ -9,6 +9,6 @@ RUN pip install --no-cache-dir -r requirements.txt
|
||||
COPY poller.py sources.toml ./
|
||||
USER ingest
|
||||
|
||||
# Ohne Argumente: Dauerbetrieb im 15-Minuten-Takt, Senke aus $DATABASE_URL.
|
||||
# Ohne Argumente: Dauerbetrieb im 2-Stunden-Takt, Senke aus $DATABASE_URL.
|
||||
# -u, damit die Logs unmittelbar im journal landen und nicht im Puffer haengen.
|
||||
ENTRYPOINT ["python", "-u", "/app/poller.py"]
|
||||
|
||||
@@ -101,8 +101,8 @@ ueber die gesamte Historie, ohne dass ein Feed erneut abgerufen wird.
|
||||
|
||||
## Verhalten
|
||||
|
||||
- **15-Minuten-Takt**, an den Slotgrenzen ausgerichtet (+30 s Versatz),
|
||||
identisch zu GDELTs Paketgrenzen — damit bleiben die Slots vergleichbar.
|
||||
- **2-Stunden-Takt**, an den Slotgrenzen ausgerichtet (+30 s Versatz), um
|
||||
unnoetigen Traffic bei den Quellen zu vermeiden.
|
||||
- **Bedingter GET** ueber ETag/Last-Modified, im Register gespeichert. Im
|
||||
Test antworteten 4 von 12 Quellen im zweiten Durchlauf mit 304.
|
||||
- **Dedup** ueber `unique (quelle, item_key)`; `item_key` ist guid, ersatzweise
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Ingest-Poller fuer den deutschen Ereignisdatensatz.
|
||||
|
||||
Liest die Quellen aus sources.toml, holt alle 15 Minuten die Feeds und legt
|
||||
Liest die Quellen aus sources.toml, holt alle 2 Stunden die Feeds und legt
|
||||
jedes neue Item roh ab. Bewusst ohne Kodierung: was hier landet, soll sich
|
||||
beliebig oft neu kodieren lassen.
|
||||
|
||||
@@ -10,7 +10,7 @@ Zwei Senken:
|
||||
--sink jsonl:/pfad/dir Schatten-Ingest als gzip-JSONL pro Slot
|
||||
|
||||
Aufrufe:
|
||||
poller.py --sink "$DATABASE_URL" # Dauerbetrieb, 15-Minuten-Takt
|
||||
poller.py --sink "$DATABASE_URL" # Dauerbetrieb, 2-Stunden-Takt
|
||||
poller.py --sink "$DATABASE_URL" --once # ein Durchlauf
|
||||
poller.py --check-robots # Lizenzstatus nachpruefen
|
||||
"""
|
||||
@@ -40,7 +40,7 @@ USER_AGENT = os.environ.get(
|
||||
"INGEST_USER_AGENT",
|
||||
"wurzelwerk-ingest/0.1 (+https://stinkwurzpresse.de/wurzelwerk; kontakt@stinkwurzpresse.de)",
|
||||
)
|
||||
TAKT = 15 * 60 # Slotlaenge in Sekunden, wie bei GDELT
|
||||
TAKT = 2 * 60 * 60 # Slotlaenge in Sekunden
|
||||
VERSATZ = 30 # Sekunden nach der Slotgrenze, nicht exakt darauf
|
||||
NS = {
|
||||
"a": "http://www.w3.org/2005/Atom",
|
||||
@@ -66,9 +66,10 @@ def _jetzt():
|
||||
|
||||
|
||||
def slot_von(ts):
|
||||
"""Auf 15 Minuten abrunden, wie GDELTs Paketgrenzen."""
|
||||
return ts.replace(second=0, microsecond=0,
|
||||
minute=(ts.minute // 15) * 15)
|
||||
"""Auf TAKT-Sekunden seit Epoch abrunden (bei 2 h also volle gerade Stunden)."""
|
||||
sekunden = int(ts.timestamp())
|
||||
return dt.datetime.fromtimestamp(
|
||||
(sekunden // TAKT) * TAKT, tz=dt.timezone.utc)
|
||||
|
||||
|
||||
def norm_titel(t):
|
||||
|
||||
+4
-3
@@ -48,7 +48,7 @@ create table if not exists raw_items (
|
||||
autor text,
|
||||
pubdate timestamptz, -- Angabe der Quelle, kann fehlen/luegen
|
||||
abgerufen_am timestamptz not null default now(),
|
||||
slot timestamptz not null, -- auf 15 min abgerundet, GDELT-kompatibel
|
||||
slot timestamptz not null, -- auf den Poll-Takt abgerundet
|
||||
sprache text not null default 'de',
|
||||
roh jsonb not null, -- alle geparsten Feldwerte, unveraendert
|
||||
|
||||
@@ -113,7 +113,8 @@ create table if not exists poll_laeufe (
|
||||
create index if not exists poll_laeufe_slot_idx on poll_laeufe (slot desc);
|
||||
create index if not exists poll_laeufe_quelle_idx on poll_laeufe (quelle, begonnen_am desc);
|
||||
|
||||
-- Welche aktive Quelle hat seit ueber sechs Stunden nichts Neues geliefert?
|
||||
-- Welche aktive Quelle hat seit ueber 24 Stunden (12 verpasste Slots bei
|
||||
-- 2-Stunden-Takt) nichts Neues geliefert?
|
||||
create or replace view quellen_stillstand as
|
||||
select q.id, q.name, max(r.abgerufen_am) as letztes_item,
|
||||
now() - max(r.abgerufen_am) as stille
|
||||
@@ -122,5 +123,5 @@ left join raw_items r on r.quelle = q.id
|
||||
where q.aktiv
|
||||
group by q.id, q.name
|
||||
having max(r.abgerufen_am) is null
|
||||
or now() - max(r.abgerufen_am) > interval '6 hours'
|
||||
or now() - max(r.abgerufen_am) > interval '24 hours'
|
||||
order by stille desc nulls first;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Ablegen unter ~/.config/containers/systemd/wurzelwerk-ingest.container,
|
||||
# danach: systemctl --user daemon-reload && systemctl --user start wurzelwerk-ingest
|
||||
#
|
||||
# Der Poller laeuft dauerhaft und taktet sich selbst auf die 15-Minuten-Grenzen.
|
||||
# Der Poller laeuft dauerhaft und taktet sich selbst auf die 2-Stunden-Grenzen.
|
||||
# Deshalb kein systemd-Timer: ein Timer wuerde den bedingten GET-Zustand
|
||||
# (ETag/Last-Modified) bei jedem Start neu aufbauen muessen.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user