Plugin che causa errori durante la ricostruzione

Oggi ho provato ad aggiornare la mia installazione di Discourse, da 2.9.0.beta9 a 2.9.0.beta10. Ma è andato terribilmente storto.

  1. Il mio primo tentativo è stato sulla console
cd /var/discourse
sudo git pull
sudo ./launcher rebuild app

Questo alla fine si è interrotto, con il seguente messaggio da qualche parte nel mezzo di tutti i log

PG::InvalidParameterValue: ERROR:  cannot extract elements from a scalar
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/pg.rb:110:in `exec'

Sono stato in grado di ripristinare semplicemente il forum avviando la vecchia immagine (che era ancora in giro).

  1. Il mio secondo tentativo è stato tramite la console web (/admin/upgrade). Ma alla fine si è bloccato con lo stesso tipo di errore: ERROR: cannot extract elements from a scalar. Tornando al pannello di aggiornamento, mi ha detto che tutti i componenti erano stati aggiornati correttamente. Ma dopo un riavvio del container, il server ha ora lanciato un errore HTTP 500 :frowning_face:

  2. Ho fatto un’installazione pulita su una macchina separata, partendo da zero. Sono stato in grado di installare la versione beta10, ma il tentativo di ripristinare da un backup ha causato esattamente lo stesso errore!

Qualcuno là fuori potrebbe essere d’aiuto?

Ho trovato la query che sta causando problemi

INSERT INTO question_answer_votes (post_id, user_id, created_at)

	SELECT
	  X.post_id AS post_id,
	  (X.value->>'user_id')::int AS user_id,
	  (X.value->>'created_at')::timestamp AS created_at
	FROM (
	  SELECT
	    post_id,
	    jsonb_array_elements(value::jsonb) AS value
	  FROM post_custom_fields WHERE name = 'vote_history'
	) AS X
	WHERE (X.value->>'action') != 'destroy'
	ORDER BY (X.value->>'created_at')::timestamp DESC
	ON CONFLICT DO NOTHING

Se ho capito bene, questo accade perché la funzione psql jsonb_array_elements si aspetta un array, ma riceve un valore NULL.

Ci sono state un paio di segnalazioni di questo:\n\nhttps://meta.discourse.org/t/bootstrap-failed-with-exit-code-1/237270\n\nhttps://meta.discourse.org/t/unable-to-install-discourse-question-answer-on-conflict-do-nothing/238128\n\nPenso che possa essere dovuto all’installazione precedente del plugin Pavilion Question/Answer?\n\nVedrò se riesco a far dare un’occhiata più approfondita a qualcuno. :+1:

Stiamo utilizzando questo plugin: https://github.com/angusmcleod/discourse-question-answer.

  • Sembra essere correlato al plugin Pavilion Question and Answer.
  • È un fork dal plugin discourse/discourse-upvotes.
1 Mi Piace

Per verificare, quali plugin hai nel tuo app.yml?

1 Mi Piace

Il sito che ho visto aveva un sacco di quei Post Custom Fields che contenevano un sacco di stringhe codificate più volte in modo da renderle inutilizzabili.

Alcune soluzioni, in ordine di complessità:

  • smettere di usare il plugin (e forse passare ai nuovi up vote)
  • eliminarli tutti
  • eliminare quelli non validi
  • modificare quei campi per trasformare nuovamente i dati in stringhe json valide.

Il sito che ho visto aveva dati non validi vecchi di anni. Sembra essere un bug esistente da anni che solo ora viene scoperto.

Potrebbe essere possibile scrivere codice per correggere le stringhe json corrotte, ma non sono riuscito a capire come farlo in 10 minuti.

Vedi Question Answer Plugin - #301 by pfaffman per esempi.

2 Mi Piace

Ci avevo pensato anch’io, ma una rapida verifica con il fork di Angus, non sembra che siano state eseguite migrazioni di dati. \u003chttps://github.com/angusmcleod/discourse-question-answer/compare/main…discourse:discourse-upvotes:main\u003e

Questo sembra una contaminazione dei dati dai vecchi post Q&A come hai detto. Trovo anche divertente che questo stia emergendo ora dato che quella migrazione è di novembre 2021 – immagino sia perché JayJay sta passando al nuovo plugin solo ora? In ogni caso, daremo un’altra occhiata a quella migrazione.

1 Mi Piace
          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/discourse/discourse-solved.git
          - git clone https://github.com/unfoldingWord-dev/discourse-mermaid.git
          - git clone https://github.com/angusmcleod/discourse-question-answer.git
          - git clone https://github.com/discourse/discourse-checklist.git
          - git clone https://github.com/discourse/discourse-cakeday.git
          - git clone https://github.com/discourse/discourse-canned-replies.git
          - git clone https://github.com/discourse/discourse-footnote.git
          - git clone https://github.com/discourse/discourse-staff-notes.git
          - git clone https://github.com/discourse/discourse-graphviz.git
          - git clone https://github.com/discourse/discourse-assign.git
          - git clone https://github.com/discourse/discourse-voting.git
          - git clone https://github.com/discourse/discourse-yearly-review.git
          - git clone https://github.com/discourse/discourse-saved-searches.git

1 Mi Piace

@nat Non passerò affatto al nuovo plugin. Sto ancora usando il set di plugin che abbiamo da parecchio tempo.

Almeno una volta al mese eseguiamo i nostri aggiornamenti, quindi non c’è un’enorme lacuna tra le versioni.

2 Mi Piace

Solo come piccola nota a margine “FYI” oltre al problema domanda-risposta, c’è anche una sostituzione per le risposte predefinite ora:

E credo che ora ci sia anche un componente a tema official Mermaid:

1 Mi Piace

Grazie. Mi occuperò di questo dopo che il mio problema originale sarà risolto :smile:

1 Mi Piace

Se rimuovessi il plugin, il ripristino del backup causerebbe comunque l’esecuzione della query errata.
Quindi, dovrei rimuovere sia il plugin sia qualsiasi tabella + query utilizzata da questo plugin.
Come farei a conoscere le tabelle coinvolte?

Hai commentato la riga del plugin e tentato una ricompilazione per confermare?

2 Mi Piace

Ci provo subito. Ho esaminato il file dump.sql, che fa parte del backup, e non c’è alcuna menzione di alcuna tabella question_answer_* . Quindi questo mi dà speranza…

1 Mi Piace

Ho avuto successo sul mio sistema di staging!

  • Plugin disabilitato
  • sudo ./launcher rebuild app
  • Ripristino del backup

Sto per lavorare sul mio sistema live. Ti terrò aggiornato.

1 Mi Piace

I dati corrotti si trovano nella tabella PostCustmField. Ma se non si dispone del plugin, non tenterà di migrare tali dati nella nuova tabella.

Il problema non è la migrazione in sé, ma il fatto che a un certo punto nel passato i dati si siano corrotti. Si è rotto, ma si è rotto in un modo che è passato inosservato per anni. Penso che forse ogni nuovo voto positivo l’abbia corrotta ulteriormente. Una soluzione ragionevole potrebbe essere quella di ignorare i dati corrotti, magari contrassegnandoli come corrotti (forse rinominando il campo personalizzato) in modo che le future migrazioni possano ignorarli e qualcuno possa risolverli manualmente, se lo desidera.

2 Mi Piace

Successo anche in live. Ho disabilitato il plugin e siamo ripartiti.
Mi chiedo ancora perché non abbia riscontrato questo problema prima. Come ho detto, ogni mese, come routine, aggiorniamo tutti i nostri sistemi, quindi avrei dovuto vedere questo problema prima.

Come potrei connettermi autonomamente al database di Discourse per verificare cosa c’è nella tabella post_custom_fields?

@Jaap-Jan_Swijnenburg Mi dispiace che tu abbia riscontrato un problema.

Rispetto la tua opinione, ma non sono d’accordo.

Il vecchio plugin QnA utilizzava il tipo di casting standard del campo personalizzato di Discourse, che serve a gestire il casting di quel campo in JSON. Ma in alcuni casi (come questo) semplicemente non funziona, motivo per cui (idealmente) è necessario implementare controlli di formato quando si lavora con campi personalizzati di Discourse (in particolare se si lavora con codice e dati piuttosto vecchi come questi). Suggerirei che è quello che il plugin Upvotes deve fare qui, da cui infatti proviene l’errore immediato.

Puoi utilizzare il plugin Data Explorer per verificare cosa hai lì.

Bene, mi fido principalmente di te su questo, e penso che siamo d’accordo. Penso che sia vero che la migrazione funziona se i dati non sono corrotti. Siamo d’accordo che se i dati sono corrotti dovrebbe fallire in modo più aggraziato di quanto non faccia ora.

Sì, ma i dati sono probabilmente stati corrotti anni fa (questo è il caso del sito che conosco bene), ma non te ne sei accorto perché non è fallito catastroficamente. Sono abbastanza sicuro che non stesse gestendo i voti come previsto, ma nessuno se ne è accorto.

Lo farei da rails, qualcosa del genere:

./launcher enter app
rails c

Poi cose come queste:

all_votes=PostCustomField.where(name: "vote_history")
likely_broken_votes=PostCustomField.where(name: "vote_history").where("value like '\\\"%'")

Guarda solo l’id e i dati:

all_votes.pluck(:id,:value)

Prendi solo un pcf:

pcf=PostCustomField.find(1234)

Correggilo

pcf.value='the stuff you really want in it'
pcf.save

Ecco cosa sta succedendo:

  1. Alcune persone hanno una versione molto vecchia del plugin “question answer” con il mio nome utente GitHub personale nell’URL del repository nel loro file app.yml.

  2. Anni fa ho trasferito il plugin QnA a paviliondev. GitHub reindirizza gli URL dei repository quando vengono trasferiti, quindi i vecchi URL con il mio nome utente personale continuavano a funzionare.

  3. Anni dopo, Pavilion ha trasferito il plugin Question Answer a Discourse. Inizialmente Discourse ha mantenuto il nome discourse-question-answer.

  4. Pochi mesi fa ho creato un mio fork del plugin ospitato in discourse, mentre era ancora chiamato discourse-question-answer.

  5. Le persone con collegamenti molto vecchi al plugin QnA con il mio account GitHub personale stavano ora clonando il mio nuovo fork del plugin discourse-question-answer significativamente aggiornato, ospitato in discourse. In altre parole, un link molto vecchio ora puntava a un fork di un nuovo plugin. Nonostante gli anni trascorsi, avrei dovuto prevederlo, quindi mi scuso per questo. Ho rimosso quel fork.

  6. Discourse ha cambiato il nome di discourse-question-answer in discourse-upvotes. Questo cambio di nome non ha avuto un impatto materiale sul tuo caso @Jaap-Jan_Swijnenburg, ma è il motivo per cui ora stai (inaspettatamente) clonando un fork di quel repository.

  7. Una migrazione in discourse/discourse-upvotes (ex discourse-question-answer) presuppone che la colonna value in post_custom_fields sia di tipo JSON.

  8. I vecchi dati creati dal plugin quando era angusmcleod/discourse-question-answer (anni fa) non sono stati salvati come JSON valido dalla “concern” HasCustomFields in discourse/discourse. Sto ipotizzando, ma questi dati sono stati probabilmente aggiunti prima che il controllo del tipo JSON venisse aggiunto 4 anni fa (È ancora possibile che si verifichino JSON non validi nei campi personalizzati registrati come JSON in casi limite).

Pertanto

  1. Quando le persone con l’URL (vecchio di anni) angusmcleod/discourse-question-answer nel loro app.yml aggiornano il loro Discourse, viene clonato il plugin della nuova versione, la migrazione viene eseguita e potenzialmente crea questo errore.

Ci sono alcune soluzioni a questo problema:

  1. @Jaap-Jan_Swijnenburg nel tuo caso devi solo rimuovere il riferimento al mio vecchio plugin QnA e potrai ricostruire il tuo sito. Questo è tutto; niente di più. Sembra che tu l’abbia fatto :+1:

  2. La migrazione del plugin discourse/discourse-upvotes potrebbe essere aggiornata per gestire valori non JSON nella colonna value in post_custom_fields.

Noterei che 2 gestirebbe anche il caso aggiuntivo di persone che desiderano effettivamente passare da una vecchia versione del plugin QnA a discourse-upvotes. In tal caso, la migrazione verrà eseguita e fallirà se una qualsiasi voce nella colonna value di post_custom_fields non è un JSON valido.

5 Mi Piace