gestisco un’installazione di Discourse piuttosto piccola da alcuni anni. Ha un traffico piuttosto basso, quindi ci è voluto un po’ per notare che l’invio di email (notifiche, riepiloghi) aveva ovviamente iniziato a fallire alcuni mesi fa. Le analisi indicano l’aggiornamento a 2.8.0.beta7 intorno al 22-10-2022, in precedenza eravamo alla 2.8.0.beta4. Almeno non ho ricevuto alcuna email da quell’installazione riguardo a post o messaggi.
Le email si accumulano in Sidekiq, con un messaggio che non riesco a collegare, né a trovare nulla di pertinente quando lo cerco: c’erano segnalazioni di messaggi undefined method, ma nessuna delle condizioni corrisponde alla mia. (Non è TLS, non è un timeout verso il server di posta, non è il plugin events, e la correzione per i media sicuri dovrebbe essere già stata applicata - inoltre, i messaggi di errore esatti erano diversi.)
Errore in Sidekiq:
Wrapped NoMethodError: undefined method `value' for #<Array:0x00007f7fd5277d68> Did you mean? values_at
La parte dopo #<Array: è diversa per ogni email in coda. Ho reinstallato Discourse su una nuova VM ieri sera e ho ripristinato da un backup recente - ma apparentemente il problema delle email è stato ripristinato con i dati
Dato che il tasso di errore ha iniziato a salire alla fine di ottobre, sono abbastanza sicuro che questo sia stato introdotto da 2.8.0.beta7:
## I plugin vanno qui
## vedi https://meta.discourse.org/t/19157 per i dettagli
hooks:
after_code:
- exec:
cd: $home/plugins
cmd:
- git clone https://github.com/discourse/docker_manager.git
## Qualsiasi comando personalizzato da eseguire dopo la compilazione
Questa è un’installazione standard? Se hai un container dati separato, è stato ricostruito? Postgres è aggiornato? (Anche se penso che ci sia ancora un controllo per questo nel codice)
Sì, è un’installazione standard; per quanto posso vedere, è in esecuzione un solo container. (Avvia una nuova VM, riassegna il DNS, apt update, apt dist-upgrade, riavvia, git pull, ./discourse-setup, configurazione basata sul Web, carica backup, ripristina backup, riabilita posta, vedi di nuovo gli errori.) Nota che la vecchia installazione è stata in grado di inviare via email il link al backup, e l’invio di email di test funziona ancora nella nuova installazione — sembrano fallire solo le email relative ai post.
root@discourse:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ac408a70305d local_discourse/app \"/sbin/boot\" 12 hours ago Up 12 hours 0.0.0.0:80-\u003e80/tcp, :::80-\u003e80/tcp, 0.0.0.0:443-\u003e443/tcp, :::443-\u003e443/tcp app
Modifica:
root@discourse:~# apt update
Hit:1 https://download.docker.com/linux/debian buster InRelease
Hit:2 http://deb.debian.org/debian buster InRelease
Get:3 http://deb.debian.org/debian buster-updates InRelease [51,9 kB]
Get:4 http://security.debian.org/debian-security buster/updates InRelease [65,4 kB]
Fetched 117 kB in 2s (60,5 kB/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
All packages are up to date.
Il primo ripristino è effettivamente fallito, però. database_restorer.rb è fallito in restore_dump a causa di link duplicati nel post_id 3841. Ho finito per sostituire questi link in un post del 2017 con uno screenshot di essi sulla vecchia installazione e facendo un altro backup; solo allora sono stato in grado di ripristinare il backup sulla nuova installazione. Dato che hai menzionato postgres, questo è successo durante CREATE INDEX con ERROR: could not create unique index \"unique_post_links\". Ulteriori informazioni: EXCEPTION: psql failed: DETAIL: Key (topic_id, post_id, url)=(1300, 3841, [redacted]) is duplicated.
Anche se non penso che questo sia direttamente correlato, ho pensato di menzionarlo.
Quindi, se nessuno conosce un modo semplice per risolvere il problema, analizziamolo correttamente. Ma ho bisogno del tuo aiuto, poiché Discourse è un’applicazione piuttosto complessa che utilizza una serie di tecnologie con cui non ho familiarità. Quindi: come vengono inviate le e-mail a Sidekiq?
Quale componente di Discourse sta fornendo a Sidekiq un metodo “value”?
Con le notifiche e-mail che smettono di funzionare dopo un aggiornamento, Discourse è purtroppo piuttosto inutile ora. Invece di un’attenzione immediata, gli argomenti richiedono ora giorni per ricevere attenzione, se mai ne ricevono, poiché le persone non effettuano sondaggi attivi nel 2022. Nessuna notifica ⇒ non è successo nulla ⇒ non è necessario controllare il sito
Sembra un indice corrotto. Non credo di averlo mai visto su postgres 13. Sembra che tu abbia risolto questi problemi su un vecchio sito e poi aggiornato eseguendo il backup e il ripristino su un nuovo sito?
Sembra che il problema abbia a che fare con qualcosa nel codice che invia notifiche, ma è un problema di sidekiq.
Come ho detto, il vecchio sito è in esecuzione, ho eseguito un backup e l’ho messo su una nuova installazione, il ripristino è fallito. Ho modificato il post indicato come colpevole finché il ripristino sulla nuova installazione non ha funzionato. Solo per vedere di avere di nuovo/ancora il problema con Sitekiq.
Il vecchio sito esegue anche postgres 13 (ma risale a diversi anni fa, quindi molto probabilmente non è iniziato con quella versione )
Ho provato con un nuovo utente, riceve correttamente la sua email di registrazione. Ma le notifiche sulle risposte ai suoi post, no; Sidekiq va in errore.
Quindi, per me questo significa che Discourse sta fornendo informazioni errate a Sidekiq quando gli istruisce di inviare Notifiche (al contrario dell’email di registrazione). Come fare ulteriori debug?
OK, quindi se gli indici vengono riparati, questo mi suggerisce che qualcosa viene chiamato con un array anziché con un modello che ha value. Il problema non è con sidekiq, in sé, ma con la funzione che sidekiq sta causando per essere chiamata.
Quindi sembra che qualcosa venga chiamato che restituisce un array anziché un singolo elemento, ma non posso indovinare cosa. Penso che dovrai guardare in /var/discourse/shared/standalone/logs/rails/production.log (o qualcosa di molto simile se le mie dita o la mia memoria mi tradiscono). Quindi puoi cercare in quei log quell’errore (o farlo accadere di nuovo in modo che sia alla fine del file). Dovresti ottenere maggiori informazioni su cosa sta fallendo lì.
Started POST "/sidekiq/retries" for 185.39.142.187 at 2022-04-11 16:31:35 +0000
start
Started GET "/sidekiq/retries" for 185.39.142.187 at 2022-04-11 16:31:35 +0000
Rendered email/notification.html.erb (Duration: 42.8ms | Allocations: 4323)
Rendered layouts/email_template.html.erb (Duration: 0.3ms | Allocations: 29)
Job exception: undefined method `value' for #<Array:0x00007ff393af6c78>
Did you mean? values_at
fail
shared/standalone/log/rails/production_errors.log è vuoto.
L’errore viene visualizzato in Admin -\u003e Log -\u003e Log errori? In tal caso, è possibile ottenere uno stack trace completo che potrebbe essere utile.
è – nel codice di Discourse? – dove Sidekiq si blocca?
Questo viene chiamato da…
228 MessageBuilder.custom_headers(SiteSetting.email_custom_headers).each do |key, _|
*229 value = header_value(key)
230
231 # Remove Auto-Submitted header for group private message emails, it does
232 # not make sense there and may hurt deliverability.
Quindi potrebbe essere un’intestazione personalizzata?
In effetti ho una voce lì:
Ho reimpostato questo ai valori predefiniti e… in realtà sembra che le notifiche via email vengano inviate di nuovo, come verificato dai lettori.
Grazie!
Rimane una domanda: perché »Auto-Submitted: auto-generated|Precedence: bulk« causa questo errore? Afferma che le intestazioni personalizzate devono essere separate da »|«.
Penso che questo sia un comportamento particolarmente spiacevole nella libreria di posta elettronica che Discourse sta utilizzando. Ecco la funzione header_value:
Per quanto ne so, @message.header[name] sta chiamando questo metodo:
Come da RFC, molti campi possono apparire più di una volta, restituiremo una stringa del valore se c’è solo un’intestazione, o se ci sono più intestazioni corrispondenti, restituiremo un array di valori nell’ordine in cui appaiono nell’intestazione ordinati dall’alto verso il basso.
Discourse imposta automaticamente un’intestazione Precedence, quindi poiché ne stai aggiungendo una anche tu tramite l’impostazione email_custom_headers, ci sono ora due intestazioni Precedence, e @message.header[\"Precedence\"] restituisce un array invece di una stringa.
Penso che questo bug verrà attivato ogni volta che email_custom_headers contiene un’intestazione che esiste già sull’oggetto del messaggio.
Questo mi sembra quello che sta succedendo (ho suggerito che qualcosa fosse un array invece di un singolo elemento, ma non riuscivo a immaginare come potesse essere vero) ed è un bug.
Cambierò il titolo e la categoria di questo argomento.
Ho unito una correzione per questo oggi, se rileviamo un’intestazione duplicata utilizziamo quella definita nel core di Discourse anziché quella personalizzata dall’impostazione del sito: