2015-05-07 11 views
5

जब मैं निम्न स्क्रिप्ट का उपयोग:Luasocket + nginx त्रुटि - lua प्रविष्टि धागा निरस्त किया गया: रनटाइम त्रुटि: सी-कॉल सीमा पार उपज के लिए प्रयास

local smtp = require("socket.smtp") 
local from = "[email protected]" 
local rcpt = "[email protected]" 
local msg = { 
    headers = { 
    to = rcpt, 
    subject = "Hi" 
    }, 
    body = "Hello" 
} 
smtp.send{from = from,rcpt = rcpt,source = smtp.message(msg)} 

मैंने एक त्रुटि संदेश हो रही है: lua entry thread aborted: runtime error: attempt to yield across C-call boundary

मैं नवीनतम luasocket का उपयोग कर रहा हूं luarocks से लूआ 5.1 के साथ luaJIT 2.1 के साथ संकलित nginx का उपयोग कर। इस त्रुटि संदेश का कारण क्या है और मैं इसे कैसे ठीक कर सकता हूं?

+0

आप एक पूर्ण उदाहरण हम 'content_by_lua_file' में प्लग देखने के लिए जहां यह विफल कर सकते हैं है? क्या यह 'smtp.send' या 'आवश्यकता' लाइन पर विफल रहता है? मुझे संदेह है कि यह पूर्व है, लेकिन पुष्टि करना चाहते हैं। –

+0

यह काफी उदाहरण है। यह प्रेषण समारोह पर विफल रहता है। – arby

उत्तर

4

smtp.send आंतरिक त्रुटियों को संभालने के लिए LuaSocket के socket.protect फ़ंक्शन का उपयोग करता है। यह फ़ंक्शन सी में कार्यान्वित किया गया है और वर्तमान रिलीज में उपज की अनुमति नहीं देता है (गिट हेड में संस्करण अब लुआ 5.2+ पर उपज करने की अनुमति देता है, चर्चा here देखें)। जाहिर है कि कोई इसके भीतर से उपज करने की कोशिश करता है। LuaSocket पैकेज में etc/dispatch.lua में (गिट हेड संस्करण का बेहतर उपयोग करें) replacement function for socket.protect है जो सभी लुआ संस्करणों (अतिरिक्त अस्थायी कोरआउटिन की लागत पर) पर उपज करने की अनुमति देनी चाहिए। तुम बहुत तरह कि लुआ समारोह के साथ सी समारोह की जगह की कोशिश कर सकते हैं:

local socket = require("socket") 
local base = _G 
-- paste modified socket.protect function here 

-- continue with your own code: 
local smtp = require("socket.smtp") 
-- ... 
+0

'कोई इसके भीतर से उपज करने का प्रयास करता है' इस मुद्दे का क्रूक्स है। यदि एक ही स्क्रिप्ट luasocket पैकेज का उपयोग कर स्टैंडअलोन LuaJIT से काम करती है, तो इसे ngx_lua से संबंधित होना चाहिए। मेरे मामले में मुद्दा यह था कि ngx_lua सॉकेट लाइब्रेरी का उपयोग किया गया था (जो अंतर्निहित उपज करता है) और फिक्स स्टॉक लुससेट लाइब्रेरी का उपयोग करना था। –

+0

'उपज' को खत्म करने से समस्या हल हो जाएगी। परन्तु तुमसे यह कैसे होता है? Socket.smtp मॉड्यूल पहले से ही 'losSocket फ़ंक्शंस को' आवश्यकता ("सॉकेट") के माध्यम से लोड करने का प्रयास करता है - यह Nginx संस्करणों के बारे में भी नहीं जानता है। आप Nginx को LuaSocket के आंतरिक कार्यों (जाहिर तौर पर) को बदलने से कैसे रोकते हैं? यहां तक ​​कि यदि आप प्रबंधित करते हैं, तो मूल लुआसॉकेट फ़ंक्शन अवरुद्ध हो रहे हैं (शायद यही कारण है कि Nginx पहले ही अपने कोरआउट-आधारित शेड्यूलर को लागू करता है) ... – siffiejoe

2

मैंने इस संदेश को कुछ हद तक समान स्थिति में देखा है; मेरे मामले में यह ngx_lua के डिजाइन से संबंधित था, जो अपने स्वयं के कोरआउटिन शेड्यूलर को लागू करता है। इसका मतलब है कि sock:receive ब्लॉक नहीं करता है, लेकिन इसके बजाय शेड्यूलर को yield निहित करता है और परिणामस्वरूप, यदि sock:receive पर कॉल स्टैक पर होने वाले सी फ़ंक्शन के साथ किया जाता है, तो आपको दिखाई देने वाली त्रुटि मिल सकती है।

मेरे मामले में मैं एक डीबग हुक से sock:receive कॉल कर रहा था और जब तक मैं लुसॉकेट के अपने संस्करण से सॉकेट विधियों का उपयोग करने के लिए स्विच नहीं करता तब तक यह त्रुटि प्राप्त नहीं हो रही थी। मैं जांचता हूं कि socket.smtp लुसॉकेट के "सामान्य" संस्करण का उपयोग कर रहा है या नहीं।

4

यह लुआजिट और सॉकेट.smtp के संयुक्त उपयोग के कारण होता है, जो एक कोरआउटिन को फैलाता है। https://github.com/openresty/lua-nginx-module/issues/376 से: https://github.com/pygy/require.lua:

@AterCattus This is a known limitation in LuaJIT (and the standard Lua 5.1 interpreter) that the require() builtin is currently implemented as a C builtin across which you cannot initiate a yield.

यह सबसे अच्छा समाधान का require.lua के इस कार्यान्वयन उपयोग करने के लिए हो सकता है की तरह लग रहा है। यह लुआजिट के साथ इस समस्या को हल करने के लिए सी के बजाए शुद्ध लुआ में लिखा गया है।

+0

हम्म, मैंने 'requ-lua 0.1.7-2' डाउनलोड किया और luarocks के माध्यम से स्थापित किया, फिर मेरी स्क्रिप्ट के शीर्ष पर 'आवश्यकता = आवश्यकता" की आवश्यकता है। मुझे अभी भी एक ही त्रुटि मिल रही है: smtp.send फ़ंक्शन से 'सी-कॉल सीमा पार करने का प्रयास करें'। – arby

+0

arby, ऐसा लगता है कि @ siffiejoe का जवाब यहां सही है। यदि socket.protect सी में लिखा गया है, तो यह वास्तविक अंतर्निहित समस्या है! –

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