2012-11-14 15 views
6

आइए कहें कि मेरे पास पोस्ट के साथ एक ब्लॉग एप्लिकेशन है। एक पोस्ट बनाने के बाद कुछ पृष्ठभूमि संचालन को संभालने के लिए एक कर्मचारी बनाया जाता है। मेरा मामला यह है कि एक पोस्ट फॉर्म जमा करने के बाद मैं किसी प्रकार का लोडिंग संदेश (gif लोडर या ऐसा) प्रदर्शित करना चाहता हूं और जब कार्यकर्ता समाप्त होता है तो मैं लोडिंग संदेश को छिपाना चाहता हूं और कार्यकर्ता द्वारा प्रदान किए गए कुछ डेटा प्रदर्शित करना चाहता हूं। मेरा सवाल यह है कि संवाद करने का सबसे अच्छा तरीका क्या है कि एक कर्मचारी ने अपना काम पूरा कर लिया है और इसे उपयोगकर्ता के लिए फ्रंटेंड पर प्रदर्शित किया है। कार्यकर्ता कॉलबैक इसपृष्ठभूमि कार्यकर्ता रेल ऐप में संचार देखते हैं

def worker_finish 
    #message the user 
end 

उत्तर

11

मुझे लगता है कि आप पृष्ठभूमि कार्यकर्ताओं होने की बात को अनदेखा किया जा सकता है की तरह कुछ लग रहा है, मूल रूप से, स्वयं को पराजित आप क्या करना का प्रयास कर रहे है। - यदि उपयोगकर्ता फॉर्म सबमिट करता है और आप अपने कंट्रोलर में नौकरी कतारबद्ध करते हैं, तो उपयोगकर्ता को कार्यकर्ता के लिए दोनों को शुरू करने और समाप्त करने की प्रतीक्षा करने के लिए, न केवल आप ही पूरा कर सकते हैं कि नियंत्रक स्वयं ही क्या कर सकता था, लेकिन आपके पास प्रक्रिया को और अधिक जटिल बना दिया (और इस प्रकार की कार्यक्षमता या तो resque, या sidekiq में नहीं बनाई गई है)।

जब एक नौकरी उतारने, एक कतार आप तुरंत ग्राहक के लिए एक प्रतिक्रिया वापस करना चाहते द्वारा संसाधित किया जा करने के लिए यानी

class PostsController < ApplicationController 
    def create 
    @post = Post.create(params[:post]) 
    BackgroundBlogOperation.enque(@post.id) 
    respond_with(@post) 
    end 
end 

BackgroundBlogOperation वर्ग तो के माध्यम से जाने के लिए एक कार्यकर्ता के लिए, एक कतार में रखा जाएगा और काम बंद करो। यदि आपको पृष्ठभूमि ब्लॉग ऑपरेशन कार्यकर्ता को समाप्त होने के बाद कुछ और करने की आवश्यकता है, तो आप ऐसा कर सकते हैं, लेकिन यह नौकरी के भीतर ही होना चाहिए, ताकि कार्यकर्ता इसके लिए ज़िम्मेदार हो सके।

यदि आप पोस्ट के बाद स्पिनर को प्रदर्शित और छुपाने की कोशिश कर रहे हैं, पेज रीलोडिंग के बिना, बस सबमिट बटन के क्लिक से पहले जावास्क्रिप्ट स्पिनर प्रदर्शित करें, और सुनिश्चित करें कि अनुरोध प्रकार जेएस है (जोड़ें: रिमोट = > फार्म के लिए सच)। फिर एक जावास्क्रिप्ट दृश्य प्रतिक्रिया है कि तरह लग रहा है बनाने के लिए:

class PostsController < ApplicationController 
    respond_to :js, :only => [:create] 
    def create 
    @post = Post.create(params[:post]) 
    BackgroundBlogOperation.enque(@post.id) 
    respond_with(@post) 
    end 
end 

और create.js.erb, यह भी एक संदेश उन्हें यह बताने कि जो कुछ भी आप पृष्ठभूमि में कर रहे हैं, कतार में है अगर इसकी अधिक बनाने की तुलना में जटिल संलग्न कर सकता है एक पोस्ट या जो भी हो।

$("#spinner").hide(); 

अब - क्या आप मूल रूप से पूछ रहे थे doesent हालांकि किसी भी उद्देश्य पूरा (क्योंकि प्रदर्शित करने और नौकरी कार्रवाई पूरी करने के नियंत्रक के लिए इंतजार की आवश्यकता होगी के पूरा होने पर स्पिनर को छिपाने के लिए) - वहाँ स्थितियों में, जहां कर रहे हैं क्लाइंट को प्रदर्शित करना कि नौकरी प्रसंस्करण समाप्त हो गया है उपयोगी है।

सबसे पहले एक परिदृश्य को परिभाषित करने देता है जहां पृष्ठभूमि प्रसंस्करण वास्तव में उपयोगी है। आइए कहें कि आपके पास एक बटन है जो क्लिक करते समय, कुछ बाहरी एपीआई से डेटा खींच लेगा, और बाहरी साइट से डेटा प्राप्त करने के बाद, आप प्रतिक्रिया के आधार पर डेटाबेस ऑपरेशन कर रहे हैं। यह पृष्ठभूमि प्रक्रिया का उपयोग करने का एक अच्छा उदाहरण होगा। अब

class ApiController < ApplicationController 
    respond_to :js, :only => [:create] 

    def sync_tweets 
    TwitterApiJob.enque(current_user.twitter_username) 
    respond_with(message: 'Syncing Tweets') 
    end 

end 

, उपयोगकर्ता जब ट्वीट्स समाप्त कर दिया है सिंक्रनाइज़ में थोड़ा और अधिक जटिल है बताने के लिए है, और आप 3 बुनियादी विकल्प होते हैं: असल में नियंत्रक में आप की तरह कुछ करना होगा

1) सूचित करें उपयोगकर्ता ईमेल के माध्यम से (आमतौर पर सबसे खराब विकल्प आईएमओ) 2) रेलवे चलाने के लिए कुछ प्रकार के एचटीएमएल 5 या वेबस्केट सक्षम रेल सर्वर का उपयोग करें, और क्लाइंट को वेबसाकेट के माध्यम से एक पुश भेजें, जो कि बहुत अच्छा है, ज्यादातर मामलों में ओवरकिल और दायरे से बाहर है इस प्रतिक्रिया का। यदि आप अपने विकल्पों को देखना चाहते हैं तो Google वेबसाइकिल धक्का देता है। 3) ज्यादातर मामलों के लिए सबसे अच्छा विकल्प IMO, एक notifcations मॉडल उपयोगकर्ता अधिसूचना के सभी प्रकार संभाल करने के लिए बनाएँ, और अपने काम में, काम पूरा होने के बाद,

Notification.create(:user_id => user.id, :message => 'Sync has finished', type => 'sync_complete') 

फिर, अगले पृष्ठ उपयोगकर्ता अनुरोधों की तरह कुछ करना , हेडर टूलबार में या कहीं भी, मुझे एक नोटिस होगा कि उपयोगकर्ता को अपठित अधिसूचनाएं हैं, ताकि उपयोगकर्ता को उस पर क्लिक करने के लिए चेतावनी दी जा सके।

--- साथ ही मुझे लगता है कि आपकी पोस्ट में आपने बताया है कि आप resque का उपयोग कर रहे हैं। मैंने रेज्यूक की कोशिश की और यह सभ्य था, लेकिन मैंने इसे उत्पादन में डीबग करने के लिए अतिसंवेदनशील पाया, और यह पागल स्मृति का उपयोग करता था - अगर आप पहले से नहीं हैं, तो मैं आपको साइडकीक की जांच करने की सलाह दूंगा, यह रेडिस का भी उपयोग करता है लेकिन यह जितना तेज़ होता है सूत्र:

https://github.com/mperham/sidekiq

यह बहुत तेजी से होता है, क्लीनर, और सेटअप पाने के लिए है, imho आसान।

+0

हालांकि प्रस्तुत केस का मामला आदर्श नहीं हो सकता है, उदाहरण के लिए रिपोर्ट चलाने के लिए कार्यक्षमता बहुत उपयोगी हो सकती है। – aaandre

संबंधित मुद्दे