2014-11-22 15 views
5

Questo funziona correttamente nel mio controller.Richieste di accodamento (lavoro ritardato) durante il download di file di dimensioni CSV di grandi dimensioni come processo in background

def export_list_sites_as_csv 
    require "csv" 
    csv_string = CSV.generate do |csv| 
     csv << ["id","name", 'etc'] 
     @search.relation.not_archived.each do |site| 
     csv << [site.id, site.name, site.etc] 
     end 
    end 
    send_data csv_string, 
       :type => 'text/csv', 
       :filename => '_sites.csv', 
       :disposition => 'attachment' 

    end 

@search variabile dipende filtro utente, a misura che metterà sacco di carico sulla RAM, UX non è buona. Poiché le altre richieste verranno messe in attesa fino a quando la richiesta corrente non viene notificata. Il che sta anche bloccando il mio sistema. Quindi, cerca di eseguire il processo in background e di far sapere all'utente quando è pronto per il download.

Quando provo a passare al modello.

ottengo un metodo non definito errore di `Send_Data' per # < \ Class: 0x9f8bed0>

mi sto muovendo per modello, perché devo chiamare lavoro in ritardo su di esso.

Gestione di CSV e lavoro differito per la prima volta.

Modifica: ActionController::Streaming è disponibile solo in Controller in modo diverso? più spesso o no, questo non sta andando da nessuna parte.

come D-Side risposta dice, dovrò cercare altri modi.

Edit2: seguito http://railscasts.com/episodes/171-delayed-job sono stato in grado di fare

class ExportCsv < Struct(:site_ids, :user_id) 

def perform 
    require "csv" 
    sites = Site.where(id: site_ids) 
    CSV.open("tmp/#{user_id}.csv", "w+") do |csv| 
     csv << ["id","name", 'etc'] 
     sites.each do |site| 
     csv << .... 
     end 
    end 
    end 


    def after(job) 
    send_file(
     .... 
    ) 
    end 

end 

Come utilizzare ActionController::Streaming all'interno di una classe personalizzata ExportCsv, o Model

Edit:

comprensione circa la sincronizzazione e la come ho affrontato la situazione,

Risposta: http://imnithin.github.io/csv_download_with_delayed_job.html

+0

'send_data' è il metodo disponibile solo in' ActionController :: Streaming'. –

+0

quindi c'è un modo per aggirare? o per chiamare il lavoro in ritardo su questo metodo. – Nithin

+0

penso, puoi fare come, chiamare la parte generata da csv nel modello come hai fatto, e chiamare quel metodo nel controller dopo aver messo la variabile risultato con send_data nello stesso controller. – amtest

risposta

2

La cosa si sta cercando di fare sconfigge lo scopo di DelayedJob.

Quando un utente effettua una richiesta, il server deve fornire una risposta per poterlo riempire. Il problema è che alcune richieste richiedono molto tempo per essere completate e l'utente deve aggrapparsi e attendere fino al termine. Un caso classico – consegna di email massiccia, ma ce ne sono altri, come già accennato, come la generazione di suite di dati. Qualunque cosa. Ci vuole più tempo per completare il tempo che puoi permetterti al tuo utente di aspettare.

Ora arriva DelayedJob. Esegue una determinata azione senza rispondere al contesto di una query. Non ha bisogno di sbrigarsi. Ma non puoi semplicemente dare uno schiaffo send_data per questo: non ci sarà alcuna richiesta perché risponda allo. Invece, dovrebbe scrivere i risultati del lavoro svolto in una memoria persistente.

Hai diversi modi per rimuoverlo.

  • È possibile ricevere un avviso via email quando il set di dati è pronto. Puoi persino allegarlo all'e-mail, ma non lo consiglierei: non puoi fare affidamento sulla disponibilità dei provider di posta elettronica ad accettare una grossa fetta di dati. Crea un collegamento per scaricare il set di dati e inviarlo.
    • DelayedJob dovrà rendere il set di dati, salvarlo nel file, ottenere il collegamento e inviarlo in un messaggio di posta elettronica a un utente.
  • Creare una sezione (una società di modello, controller e viste) della tua app che suona come "Richieste completate", potrebbe far parte del profilo dell'utente. La richiesta di "avvio" dovrebbe chiedere all'utente di tornare più tardi e cercare in quell'elenco per ottenere il risultato.
    • DelayedJob dovrà inserire una voce in quella lista lì dopo che la richiesta è stata completata. Il modo in cui il set di dati è archiviato è irrilevante, ma è possibile combinarlo in un modo superiore, salvarlo in un file e visualizzarne un collegamento.
+0

È perfettamente corretto! –

Problemi correlati