2012-04-17 11 views
38

मेरे पास सर्वर/statusboard.js में निम्न कोड है;सर्वर पर संग्रह.इन्सर्ट को कॉल करते समय उल्का कोड हमेशा फाइबर के भीतर चलाना चाहिए "

var require = __meteor_bootstrap__.require, 
    request = require("request") 


function getServices(services) { 
    services = []; 
    request('http://some-server/vshell/index.php?type=services&mode=json', function (error, response, body) { 
    var resJSON = JSON.parse(body); 
    _.each(resJSON, function(data) { 
     var host = data["host_name"]; 
     var service = data["service_description"]; 
     var hardState = data["last_hard_state"]; 
     var currState = data["current_state"]; 
     services+={host: host, service: service, hardState: hardState, currState: currState}; 
     Services.insert({host: host, service: service, hardState: hardState, currState: currState}); 
    }); 
    }); 
} 

Meteor.startup(function() { 
    var services = []; 
    getServices(services); 
    console.log(services); 
}); 

असल में, यह JSON फ़ीड से कुछ डेटा खींच रहा है और उसे संग्रह में धक्का देने की कोशिश कर रहा है।

जब मैं उल्का शुरू करता हूं तो मुझे निम्नलिखित अपवाद मिलता है;

app/packages/livedata/livedata_server.js:781 
     throw exception; 
      ^
Error: Meteor code must always run within a Fiber 
    at [object Object].withValue (app/packages/meteor/dynamics_nodejs.js:22:15) 
    at [object Object].apply (app/packages/livedata/livedata_server.js:767:45) 
    at [object Object].insert (app/packages/mongo-livedata/collection.js:199:21) 
    at app/server/statusboard.js:15:16 
    at Array.forEach (native) 
    at Function.<anonymous> (app/packages/underscore/underscore.js:76:11) 
    at Request._callback (app/server/statusboard.js:9:7) 
    at Request.callback (/usr/local/meteor/lib/node_modules/request/main.js:108:22) 
    at Request.<anonymous> (/usr/local/meteor/lib/node_modules/request/main.js:468:18) 
    at Request.emit (events.js:67:17) 
Exited with code: 1 

मुझे यह भी सुनिश्चित नहीं है कि त्रुटि का क्या अर्थ है। क्या किसी के पास कोई विचार है, या एक अलग दृष्टिकोण का सुझाव दे सकता है?

+0

मैं यह स्पष्ट है कि "सेवाएं" दोनों ग्राहक के लिए एक अलग फ़ाइल में कहीं परिभाषित किया गया है (सामान्य बनाना चाहिए और सर्वर)। –

+0

यह लाइन समस्या है: 'सेवाएं।सम्मिलित करें ({होस्ट: होस्ट, सेवा: सेवा, हार्डस्टेट: हार्डस्टेट, currState: currState}); ' मुझे लगता है क्योंकि यह कॉलबैक में है, इस समय आपके लिए परीक्षण करने का कोई तरीका नहीं है। – jonathanKingston

+2

उल्का में अब एक HTTP अनुरोध लाइब्रेरी शामिल है जो आपके मामले को बहुत आसान बनाता है: http://docs.meteor.com/#meteor_http – debergalis

उत्तर

15

जैसा ऊपर बताया गया है, क्योंकि यह कॉलबैक के भीतर आपका निष्पादन कोड है।

सर्वर-साइड पर चल रहे किसी भी कोड को फाइबर के भीतर निहित करने की आवश्यकता है।

कोशिश अपने getServices बदलते इस तरह देखने के लिए काम करते हैं:

function getServices(services) { 
    Fiber(function() { 
    services = []; 
    request('http://some-server/vshell/index.php?type=services&mode=json', function (error, response, body) { 
     var resJSON = JSON.parse(body); 
     _.each(resJSON, function(data) { 
     var host = data["host_name"]; 
     var service = data["service_description"]; 
     var hardState = data["last_hard_state"]; 
     var currState = data["current_state"]; 
     services+={host: host, service: service, hardState: hardState, currState: currState}; 
     Services.insert({host: host, service: service, hardState: hardState, currState: currState}); 
     }); 
    }); 
    }).run(); 
} 

मैं सिर्फ एक समान समस्या में पड़ गए और यह मेरे लिए काम किया। मुझे जो कहना है वह यह है कि मैं इसके लिए बहुत नया हूं और मुझे नहीं पता कि यह कैसे किया जाना चाहिए।

शायद आप केवल फाइबर में अपने सम्मिलन कथन को लपेटने से दूर हो सकते हैं, लेकिन मैं सकारात्मक नहीं हूं।

7

मेरे परीक्षणों के आधार पर आपको उस कोड में सम्मिलित करना होगा जिसे मैंने परीक्षण किया है जो उपरोक्त उदाहरण के समान है।

उदाहरण के लिए, मैंने यह किया और यह अभी भी फाइबर त्रुटि के साथ विफल रहा।

function insertPost(args) { 
    if(args) { 
Fiber(function() { 
    post_text = args.text.slice(0,140); 
    T.post('statuses/update', { status: post_text }, 
     function(err, reply) {   
      if(reply){ 
       // TODO remove console output 
       console.log('reply: ' + JSON.stringify(reply,0,4)); 
       console.log('incoming twitter string: ' + reply.id_str); 
       // TODO insert record 
       var ts = Date.now(); 
       id = Posts.insert({ 
        post: post_text, 
        twitter_id_str: reply.id_str, 
        created: ts 
       }); 
      }else { 
       console.log('error: ' + JSON.stringify(err,0,4)); 
       // TODO maybe store locally even though it failed on twitter 
       // and run service in background to push them later? 
      } 
     } 
    ); 
}).run(); 
    } 
} 

मैंने यह किया और यह कोई त्रुटि के बिना ठीक चला गया।

function insertPost(args) { 
    if(args) { 
post_text = args.text.slice(0,140); 
T.post('statuses/update', { status: post_text }, 
    function(err, reply) {   
     if(reply){ 
      // TODO remove console output 
      console.log('reply: ' + JSON.stringify(reply,0,4)); 
      console.log('incoming twitter string: ' + reply.id_str); 
      // TODO insert record 
      var ts = Date.now(); 
      Fiber(function() { 
       id = Posts.insert({ 
        post: post_text, 
        twitter_id_str: reply.id_str, 
        created: ts 
       }); 
      }).run(); 
     }else { 
      console.log('error: ' + JSON.stringify(err,0,4)); 
      // TODO maybe store locally even though it failed on twitter 
      // and run service in background to push them later? 
     } 
    } 
); 
    } 
} 

मैंने सोचा कि इससे दूसरों को इस मुद्दे का सामना करने में मदद मिल सकती है। मैंने अभी तक आंतरिक कोड के बाद एसिन्ची प्रकार की बाहरी सेवा को कॉल करने और फाइबर में लपेटने का परीक्षण नहीं किया है। यह भी परीक्षण के लायक हो सकता है। मेरे मामले में मुझे पता होना चाहिए कि मेरी स्थानीय कार्रवाई करने से पहले रिमोट एक्शन हुआ था।

आशा है कि यह इस प्रश्न धागे में योगदान देगा।

+0

[02:33:57] यह एक बुरा जवाब है, मुझे उस पर टिप्पणी करनी चाहिए। [02:34:20] जो एक फाइबर बनाता है, लेकिन यह इसके अंदर उपयोगी उल्का संदर्भ स्थापित नहीं करता है, और यह वास्तव में बाहरी धागे पर बाहरी विधि को अवरुद्ध नहीं करता है। –

+2

@TomWijsman जो तब सटीक है? विधि में कोड के पूरे ब्लॉक के आसपास फाइबर? –

+1

[01:40:21] 1: लिखने की बाड़ को हटा दें। इस के उदाहरण के लिए पैकेज/उल्का/timers.js में Meteor.setTimeout के कार्यान्वयन को देखें। [01:41:19] 2: जो भी कॉलबैक आपने नए फाइबर में परिभाषित किया है उसे लपेटें, ताकि जब तक आपकी कॉलबैक रन न हो जाए तब तक विधि वापस नहीं आती है। इस तरह सिंक्रोनस उल्का एपीआई लागू किए जाते हैं, जैसे संकुल/मोंगो-लिविटाटा/mongo_driver.js [01:42:02] सही उत्तर वास्तव में 3 है: जो भी आप कोशिश कर रहे हैं उसके लिए एक सभ्य सिंक्रोनस एपीआई लागू नहीं करने के लिए हमें चिल्लाओ करने के लिए :) –

47

बस अपने फ़ंक्शन को फाइबर में लपेटना पर्याप्त नहीं हो सकता है और अप्रत्याशित व्यवहार का कारण बन सकता है।

कारण फाइबर के साथ, उल्का को फाइबर से जुड़े चर के सेट की आवश्यकता होती है। उल्का एक गतिशील क्षेत्र के रूप में एक फाइबर से जुड़े डेटा का उपयोग करता है और तीसरे पक्ष एपीआई के साथ इसका उपयोग करने का सबसे आसान तरीका Meteor.bindEnvironment का उपयोग करना है।

T.post('someurl', Meteor.bindEnvironment(function (err, res) { 
    // do stuff 
    // can access Meteor.userId 
    // still have MongoDB write fence 
}, function() { console.log('Failed to bind environment'); })); 

evented दिमाग पर इन वीडियो देखें यदि आप और अधिक जानना चाहता हूँ: https://www.eventedmind.com/posts/meteor-dynamic-scoping-with-environment-variables https://www.eventedmind.com/posts/meteor-what-is-meteor-bindenvironment

+1

के भीतर एक मूल्य कैसे वापस कर सकते हैं यह मेरे लिए चाल है। स्वीकृत उत्तर काम नहीं किया, क्योंकि 'फाइबर' मौजूद नहीं है! –

+1

फाइबर केवल सर्वर-साइड पर मौजूद हैं, क्या आपने इसे सामान्य या क्लाइंटसाइड कोड में रखा है? – Thomas

+1

यह स्वीकृत उत्तर –

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