Algoritmo per tenere traccia dell'avanzamento del metodo del controller in esecuzione in background

4

Sto usando il framework Codeigniter per PHP su piattaforma Windows. Il mio problema è che sto cercando di tenere traccia dell'avanzamento di un metodo di controllo in esecuzione in background. Il controller estrae i dati dal database (MySQL) quindi esegue qualche elaborazione e quindi memorizza nuovamente i risultati nel database. Il processo completo di cui sopra può essere considerato come una singola attività. È possibile assegnare una nuova attività mentre è in esecuzione un'altra attività. L'attività appena assegnata verrà aggiunta in una coda. Quindi, se posso tenere traccia dell'avanzamento del controller, posso mostrare lo stato di ciascuna di queste attività. Come se fosse possibile visualizzare lo stato "In sospeso" per le attività in coda, "In corso" per le attività in esecuzione e "Fatto" per le attività completate.

Problema principale:

Ora la prima cosa di cui ho bisogno per trovare è un algoritmo per tenere traccia dell'avanzamento della quantità di esecuzione che il metodo del controller ha completato e che significa tenere traccia di quanto quantità di metodo ha completato l'esecuzione. Ad esempio, questo script PHP tiene traccia dell'avanzamento degli array . Qui lo stato e lo stato attuali dopo l'esecuzione totale sono noti, quindi è possibile tracciare i suoi progressi. Ma non sono in grado di escogitare nulla di analogo nel mio caso.

Forse ciò che sto cercando di ottenere è programmaticamente impossibile. Se non è possibile, suggeriscimi una soluzione alternativa o un approccio completamente nuovo. Se alcuni dettagli sono in sospeso, puoi menzionarli. Scusa per la mia ignoranza, questo è il mio primo post qui. Ti do il benvenuto per sottolineare i miei errori.

Modifica

Struttura del database:

Gli URL e le parole chiave vengono prima inseriti dall'utente che sono memorizzati in una tabella di database chiamata link_master e keyword_master rispettivamente. Quindi le parole chiave vengono estratte da tutti i link presenti in questa tabella e confrontate con le parole chiave inserite dall'utente e viene calcolata la loro frequenza, che è il risultato finale. E i risultati sono memorizzati in un'altra tabella chiamata link_result . Ora i collegamenti secondari vengono estratti dai link del dominio e archiviati in una tabella chiamata sott_link_master . Ora di nuovo le parole chiave vengono estratte da questi collegamenti secondari ei risultati corrispondenti sono memorizzati in una tabella chiamata sub_link_result .

Il numero di record non può essere definito in anticipo in quanto il numero di link su qualsiasi pagina web può essere diverso. Si può conoscere solo la cardinalità della tabella link_result che sarà uguale alla moltiplicazione del numero di parole chiave e URL (s).

Inserisco più record alla volta utilizzando questa risorsa .

Struttura del controller:

Il controller estrae le parole chiave da una pagina Web e estrae anche le parole chiave da tutti i link presenti su quella pagina. Esiste un metodo chiamato crawlLink . Ho usato Rolling Curl per estrarre parole chiave e contenuti di pagine web. Ha una funzione di callback che ho usato per estrarre parole chiave insieme a generare risultati ed estrarre link secondari validi. Esiste un metodo insertResult che memorizza i risultati per link e sottol link nelle rispettive tabelle.

Sì, l'elaborazione dipende dal numero di record. Maggiore è il numero di record, maggiore è il tempo necessario per l'esecuzione:

Considera questo scenario:

Numero di collegamenti di dominio = 1

Numero di parole chiave = 3

Numero di risultati di collegamenti di dominio generati = 3 (3 x 1 come descritto nella domanda)

Numero di collegamenti secondari generati = 41

Numero di collegamenti secondari Risultato = 117 (41 x 3 = 123 ma alcuni link non sono validi o ricercabili)

Tempo approssimativo necessario per completare il processo sopra = 55 secondi.

Il risultato sopra è per un singolo link. Voglio tenere traccia dell'avanzamento dei risultati sopra riportati che vengono memorizzati nel database. Quando tutti i risultati sono memorizzati, l'attività è completa. Se i risultati vengono memorizzati, l'attività è In corso. Non sono chiaro come posso monitorare questo progresso.

    
posta SilentAssassin 20.02.2013 - 08:28
fonte

3 risposte

1

Anche se sarebbe quasi impossibile tracciare il% completo accuratamente a causa di un numero indeterminato di link e parole chiave, è possibile mostrare uno stato approssimativo tramite la profondità. Ad esempio la prima profondità sarebbe l'url / s elaborato dal livello superiore.

(100 / Pagine totali) * Pagine elaborate =% stato attuale

Pagine totali = Seleziona conteggio () da master_links
Pagine elaborate = Seleziona il conteggio (
) di master_links dove elaborato = true. Quando hai elaborato la pagina, imposta semplicemente il flag nel db.

(Ciò potrebbe essere fatto anche popolando un array con i tuoi valori db e usando il valore dell'indice man mano che le pagine vengono elaborate)

Nota: puoi ottenere lo stato solo per ogni livello. Non iniziare a eseguire la scansione dei tuoi sub_links finché tutti i master_links non vengono sottoposti a scansione: ciò consentirà anche di evitare la scansione dell'URL duplicata e dovrebbe avere un impatto minimo sul tempo totale.

I quadrati nel diagramma sottostante rappresentano le pagine che devono essere elaborate. All'interno di ogni casella è presente la percentuale completa se le hai elaborate da sinistra a destra. Questo è a scopo illustrativo la percentuale sarebbe basata su questo:

Il tuo output mostrerebbe la percentuale completa di quel livello:
per esempio. Link principali 40% completi
o
per esempio. Link principali 100%
     Sottopunti 49,8%

Questo dovrebbe comunque fornire informazioni sufficienti per indicare i progressi, dopotutto non si può intuire la densità effettiva di parole chiave e collegamenti ...

    
risposta data 20.02.2013 - 12:31
fonte
0

Sono solo un programmatore pigro per suggerire che, poiché il processo in background sa dove si trova, può fare rapporto al database una volta per ciclo?

Il motivo per cui lo chiedo è che una volta ho scritto un processo in background il cui compito era importare record da altri database. Il database, la tabella necessaria, sono stati annotati in una tabella denominata command_queue e ID riga sul vecchio sistema aggiunto a command_queue che l'attività in background avvierebbe una nuova transazione, bloccando la riga che rappresenta il comando su cui si sta eseguendo, aggiungendo il numero di ID assegnato dal sistema (che ottenuto registrandosi su un'altra tabella), quindi iniziare a lavorare e quindi aggiornare la nuova tabella aggiungendo il vecchio ID ai nuovi dati di riga e quindi rilasciare la riga command_queue come completa e confermare la transazione.

In questo modo potrei avere più thread in esecuzione contemporaneamente, in grado di far fronte a un'interruzione di corrente (se mai dovesse succedere) e di riprendermi da qualsiasi livello di catastrofe. Allo stesso modo, potrei monopolizzare la scatola con molti thread se ci fosse molto lavoro da fare e specialmente quando siamo andati a casa e i server erano inattivi.

Nell'accettore di codice avevo una vista che emetterebbe il numero di comandi rimasti per eseguire quanti sono stati elaborati e quali sono le dimensioni delle tabelle nel database che hanno ricevuto una menzione nell'elenco dei comandi. (C'era anche un comando di stop per ogni thread di lavoro).

Usando un po 'di bontà javascript, la vista appariva piuttosto impressionante con tachimetri, grafici a torta e così via. Ai manager piaceva vedere quel genere di cose.

Non ho dovuto capire cosa stavano facendo, come ho avuto modo di dirmi in dettaglio. Anche se potrei andare a guardare come ho usato (distaccato) le istanze di schermo per ogni processo e potrei vedere l'output. Ha aiutato che volevo essere il primo programmatore a scrivere un progetto che anche con migliaia di utenti al secondo ci sarebbe stata una crisi zero, zero perdite di dati, zero interruzioni mai.

Modifica Se non ti piace usare lo schermo e hai compilato PHP con --enable-pcntl allora puoi usare pcntl_fork per creare i processi in background e setproctitle per notare i progressi e poi quando visualizzi il processo elenca il tuo processo che si rinomina per darti un indizio.

    
risposta data 30.03.2013 - 11:36
fonte
0

Esistono tre modi per monitorare lo stato di avanzamento di un'attività PHP in esecuzione sul server.

Usa WebSockets per monitorare in tempo reale

Probabile esagerazione per un'attività di 55 secondi.

Usando Ratchet puoi creare un servizio socket a cui puoi connetterti tramite Javascript e inviare dati in PHP in tempo reale al browser . La connessione socket è attiva fino a quando è connesso il socket Javascript.

Chiamate AJAX a tempo

Chiama il server su un intervallo regolare per ricevere dati sul processo dell'attività corrente (questo è ciò che faccio sempre). La richiesta restituirebbe una risposta JSON con lo stato attuale.

$.ajax({url: "/monitor_task?task_id=3"}).done(function(data) { alert(data); });

Condivisione dei dati di avanzamento

Ci sono due modi per condividere le tue attività sul lato server.

  1. Scrivi il progresso in una tabella di database e fai in modo che l'azione monitor_task legga quel valore.
  2. Utilizza un oggetto memoria condivisa (proprio come un file) e leggi il tuo monitor_task quel file.

Aggiornamento della pagina corrente

Crea una vista che mostri i progressi attuali e posiziona un meta aggiornamento con un intervallo. Questo dirà al browser di aggiornare sempre la pagina per l'intervallo.

<meta http-equiv="refresh" content="5" />
    
risposta data 27.08.2013 - 14:39
fonte

Leggi altre domande sui tag