2015-10-23 8 views
6

कहा गया था, मैं ETIMEDOUT या ECONNRESET त्रुटि प्राप्त करता हूं, जब चलाता है तो त्रुटि Callback was already called त्रुटि होती है।Async.js - ETIMEDOUT और कॉलबैक को पहले से ही

पहले मैंने सोचा था कि ऐसा इसलिए था क्योंकि onEachLimitItem कॉलबैक को कॉल करने से पहले मुझे return शामिल नहीं था। तो मैंने इसे async multiple callbacks documentation प्रति शामिल किया। अभी भी इसे हल नहीं कर रहा है। मैंने त्रुटि घटना को हटाने और त्रुटि घटना में प्रत्येक लाइव पर कॉलबैक को हटाने का भी प्रयास किया है, लेकिन न तो काम किया है। मैंने Callback already called के मुद्दे के आसपास अन्य SO प्रश्नों को देखा है, लेकिन क्योंकि वे धाराओं से चिंतित नहीं हैं, मुझे समाधान नहीं मिला।

मेरी समझ यह है कि यदि स्ट्रीम ECONNRESET जैसी त्रुटि का सामना करती है, तो यह त्रुटि घटना में कॉलबैक वापस कर देगी और अगली स्ट्रीम पर जायेगी, लेकिन ऐसा लगता है कि ऐसा नहीं लगता है। यह लगभग लगता है कि त्रुटि स्वयं को हल करती है यानी यह फिर से कनेक्ट हो जाती है और फिर से Azure को गड़बड़ किए गए स्टीम को भेजने की कोशिश करता है और यह काम करता है, फिर यह 'फिनिश' ईवेंट ट्रिगर करता है, और हमें Callback already called मिलता है।

क्या मैं स्ट्रीम घटनाओं के भीतर कॉलबैक को सही तरीके से प्रबंधित कर रहा हूं?

var Q = require('q'); 
var async = require('async'); 
var webshot = require('webshot'); 
var Readable = require('stream').Readable; 
var azure = require('azure-storage'); 

var blob = azure.createBlobService('123', '112244'); 
var container = 'awesome'; 

var countries = [ 
    'en-us', 'es-us', 'en-au', 'de-at', 'pt-br', 'en-ca', 'fr-ca', 'cs-cz', 'ar-ly', 'es-ve', 
    'da-dk', 'fi-fi', 'de-de', 'hu-hu', 'ko-kr', 'es-xl', 'en-my', 'nl-nl', 'en-nz', 'nb-no', 
    'nn-no', 'pl-pl', 'ro-ro', 'ru-ru', 'ca-es', 'es-es', 'eu-es', 'gl-es', 'en-gb', 'es-ar', 
    'nl-be', 'bg-bg', 'es-cl', 'zh-cn', 'es-co', 'es-cr', 'es-ec', 'et-ee', 'fr-fr', 'el-gr', 
    'zh-hk', 'en-in', 'id-id', 'en-ie', 'he-il', 'it-it', 'ja-jp', 'es-mx', 'es-pe', 'en-ph' 
]; 

var uploadStreamToStorage = function (fileName, stream, onEachLimitItem) { 
    var readable = new Readable().wrap(stream); 
    var writeable = blob.createWriteStreamToBlockBlob(container, fileName); 

    readable.pipe(writeable); 

    writeable.on('error', function (error) { 
     return onEachLimitItem.call(error); 
    }); 

    writeable.on('finish', function() { 
     onEachLimitItem.call(null); 
    }); 
}; 

var takeIndividualScreenshot = function (ID, country, onEachLimitItem) { 
    var fileName = ID + '-' + country + '.jpg'; 
    var url = 'https://example.com/' + country + '/' + ID; 

    webshot(url, function (error, stream) { 
     if (error) { throw 'Screenshot not taken'; } 

     uploadStreamToStorage(fileName, stream, onEachLimitItem); 

    }); 
}; 

var getAllCountriesOfId = function (ID) { 
    var deferred = Q.defer(); 
    var limit = 5; 

    function onEachCountry(country, onEachLimitItem) { 
     takeIndividualScreenshot(ID, country, onEachLimitItem); 
    } 

    async.eachLimit(countries, limit, onEachCountry, function (error) { 
     if (error) { deferred.reject(error); } 
     deferred.resolve(); 
    }); 

    return deferred.promise; 
}; 

var createContainer = function() { 
    var df = Q.defer(); 
    var self = this; 

    blob.createContainerIfNotExists(this.container, this.containerOptions, function (error) { 

     if (error) { df.reject(error); } 

     df.resolve(self.container); 
    }); 

    return df.promise; 
}; 

createContainer() 
    .then(function() { 
     return getAllCountriesOfId('211007'); 
    }) 
    .then(function() { 
     return getAllCountriesOfId('123456'); 
    }) 
    .fail(function (error) { 
     log.info(error); 
    }); 

enter image description here

+0

एक बात मैं देख रहा हूँ कि जब मैं यह मेरी वी एम (रैम की 3GB) पर बनाम स्थानीय स्तर पर (रैम 8GB) चलाने के लिए, कि स्क्रिप्ट जब 'ECONNRESET' त्रुटि फेंक करने के लिए जारी है मैं इसे मेरे वीएम पर चलाएं। – Blexy

उत्तर

4

आप अपने कॉलबैक दे रहे हैं, दो बार कॉल करने के रूप में आप पहले से ही पता है। प्रश्न है; क्या आप सभी त्रुटियों पर रोकना चाहते हैं क्योंकि आप स्ट्रीम को पुन: सक्रिय कर रहे हैं या आप स्ट्रीम से सभी त्रुटियों को जमा करना चाहते हैं?

वहाँ पकड़ने और त्रुटियों जो आप पहले से ही कर रहे हैं संभाल करने के लिए कई तरीके हैं, लेकिन आप फेंक नहीं कर रहे हैं क्योंकि त्रुटि वस्तु घातक रूप से त्रुटि के लिए अपने डेटा स्ट्रीम से अतिरिक्त कॉल के लिए अग्रणी।

आपके कोड में वास्तविक समस्या आपकी वापसी के दायरे के कारण है। आप त्रुटि हैंडलिंग और कॉलबैक और पड़ाव स्क्रिप्ट निष्पादन वापस जाने के लिए कोशिश कर रहे हैं जब घंटे वापसी की गुंजाइश धाराओं त्रुटि हैंडलर लिए स्थानीय है, नहीं वैश्विक स्क्रिप्ट इसलिए स्क्रिप्ट जारी रखने और अगले वैध धारा पर जाने से पकड़ने।

writeable.on('error', function (error) { 
    // This 'return' is in the local scope of 'writable.on('error')' 
    return onEachLimitItem.call(error); 
}); 

यह शायद एक सरणी सेट कर सकता है, फिर उस कार्य के स्थानीय त्रुटि के बाहर त्रुटि को संभाल सकता है। यानी

// Set the array's scope as global to the writable.on() error 
var errResults = []; 
writeable.on('error', function (error) { 
    // Push the local scoped 'error' into the global scoped 'errResults' array 
    errResults.push(error); 
}); 

writeable.on('finish', function() { 
    // Are there any errors? 
    return (errResults.length > 0) ? 
    onEachLimitItem.call(errors) : onEachLimitItem.call(null); 
}); 

उपर्युक्त समस्या से निपटने का एक तरीका है।

मुझे यकीन नहीं है कि आपने जॉयेंट (मूल नोड.जेएस भाषा बैकर) से प्रदान की गई त्रुटि हैंडलिंग सहायता को पढ़ लिया है, लेकिन त्रुटि (नों) को संभालने पर आपको अपने विकल्पों का अच्छा विचार देना चाहिए।

https://www.joyent.com/developers/node/design/errors

+0

हाय @ jas-, मैं उपयोग कर रहा हूँ 'Q' के .fail त्रुटि श्रोता, लेकिन सिर्फ लकड़हारा है कि मैं (मैं ऊपर स्क्रिप्ट है कि जोड़ दिया है) का उपयोग कर रहा करने के लिए भेजने में त्रुटि। मैं धारा से सभी त्रुटियों को जमा करने के लिए, और स्क्रिप्ट नीचे दुर्घटनाग्रस्त आ नहीं चाहते हैं - मैं तो बस ऐसा करने के तरीके यकीन नहीं है। जॉयंट लिंक पर अब पढ़ना। – Blexy

+0

मैं क्यू से परिचित नहीं हूं, लेकिन जैसा कि मैंने बताया है कि आपकी स्क्रिप्ट त्रुटियों पर रोक नहीं रही है और दो बार बुला रही है। यह तब हो सकता है (और अपने मामले में है) जिसके साथ आप कॉलबैक त्रुटि हैंडलर लौट रहे हैं गुंजाइश की वजह से 'writeable.on()' त्रुटि हैंडलिंग कार्य करने के लिए स्थानीय है। –

+0

क्या आप एक उदाहरण प्रदान कर सकते हैं कि मैं त्रुटि को कैसे संभालेगा? धन्यवाद, यह मेरे लिए बिल्कुल नया है। – Blexy

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