2012-04-20 8 views
5

के बीच में राइनो इंजन रोक राइनो इंजन एक API कि बीच में एक स्क्रिप्ट छी के निष्पादन रोक सकता है। उदाहरण के लिए, मेरे पास एक स्क्रिप्ट फ़ाइल है जिसमें एक infinte पाश है। मैं बीच में निष्पादन को कैसे रोक सकता हूं?निष्पादन

बेशक

, मैं JVM जो स्क्रिप्ट निष्पादित करें को राइनो इंजन शुरू कर दिया रोक सकता है। लेकिन मैं इस कारण से पूरे जेवीएम सत्र को मारना नहीं चाहता क्योंकि मैंने प्रोग्राम को स्क्रिप्ट शुरू कर दिया है और राइनो इंजन भी मेरे आवेदन के समान JVM में चल रहा है।

उत्तर

5

जावास्क्रिप्ट चलाने का निष्पादन नीचे दिए तरीक़े का उपयोग करके किया जा सकता है रोक।

1) एक डमी डीबगर बनाएँ और शुरू में बनाई गई संदर्भ में संलग्न करें।

mContext = Context.enter();
निरीक्षण करने वाले डीबगर = dudeugger = new ObservingDebugger();
mContext.setDebugger (देखकर डिबगर, नया इंटीजर (0));
mContext.setGeneratingDebug (सत्य);
mContext.setOptimizationLevel (-1);

पर्यवेक्षण डिबगर कोड निम्नानुसार दिखता है।

import org.mozilla.javascript.Context; 
import org.mozilla.javascript.Scriptable; 
import org.mozilla.javascript.debug.DebugFrame; 
import org.mozilla.javascript.debug.DebuggableScript; 
import org.mozilla.javascript.debug.Debugger; 

public class ObservingDebugger implements Debugger 
{ 
boolean isDisconnected = false; 

private DebugFrame debugFrame = null; 

public boolean isDisconnected() { 
    return isDisconnected; 
} 

public void setDisconnected(boolean isDisconnected) { 
    this.isDisconnected = isDisconnected; 
    if(debugFrame != null){ 
     ((ObservingDebugFrame)debugFrame).setDisconnected(isDisconnected); 
    } 
} 

public ObservingDebugger() { 

} 

public DebugFrame getFrame(Context cx, DebuggableScript fnOrScript) 
{ 
    if(debugFrame == null){ 
     debugFrame = new ObservingDebugFrame(isDisconnected); 
    } 
    return debugFrame;  
} 

@Override 
public void handleCompilationDone(Context arg0, DebuggableScript arg1, String arg2) { } } 
// internal ObservingDebugFrame class 
class ObservingDebugFrame implements DebugFrame 
    { 
boolean isDisconnected = false; 

public boolean isDisconnected() { 
    return isDisconnected; 
} 

public void setDisconnected(boolean isDisconnected) { 
    this.isDisconnected = isDisconnected; 
} 

ObservingDebugFrame(boolean isDisconnected) 
{ 
    this.isDisconnected = isDisconnected; 
} 

public void onEnter(Context cx, Scriptable activation, 
     Scriptable thisObj, Object[] args) 
{ } 

public void onLineChange(Context cx, int lineNumber) 
{ 
    if(isDisconnected){ 
     throw new RuntimeException("Script Execution terminaed"); 
    } 
} 

public void onExceptionThrown(Context cx, Throwable ex) 
{ } 

public void onExit(Context cx, boolean byThrow, 
     Object resultOrException) 
{ } 

@Override 
public void onDebuggerStatement(Context arg0) { } } 

ObservingDebugger वर्ग बूलियन चर "isDisconnected" प्रबंधन करेगा और जब प्रयोक्ता रोकें बटन पर क्लिक करता है तो यह चर सही पर सेट है (निष्पादन बंद करना चाहता है)। एक बार परिवर्तनीय सत्य पर सेट हो जाने के बाद राइनो निष्पादन तुरंत समाप्त हो जाएगा।

observingDebugger.setDisconnected(true); 
-2

राइनो इंजन doesn't appear इस (बुरा राइनो!) करने के लिए किसी भी तंत्र है और यह बताने के लिए कि क्या यह आंतरिक सूत्र बनाता है मुश्किल है, इसलिए केवल समाधान आप मिल गया है एक ThreadGroup, भार बनाने के लिए है और राइनो निष्पादित उस समूह में एक थ्रेड के अंदर से इंजन और इसकी स्क्रिप्ट, और जब आप इसे मारना चाहते हैं, तो ThreadGroup.stop() का उपयोग करें। हां, यह बहिष्कृत है लेकिन ऐसा करने का कोई दूसरा तरीका नहीं है कि राइनो लाइब्रेरी के हिस्से पर कोई सहयोग नहीं है।

+0

@ डोनल: डिफ़ॉल्ट के रूप में इस ContextFactory उपयोग करने के लिए, बस आह्वान

InterruptableContextFactory.init() 

अपने प्रतिदेय की कॉल विधि के अंदर, आप त्रुटि पर कब्जा कर सकते हैं यह हो सकता है जनसंपर्क मोटे तौर पर काम नहीं करते क्योंकि एक बार जब मैं नया धागा बना देता हूं और राइनो इंजन को लोड करना और निष्पादित करना शुरू करता हूं, उस समय से संदर्भ पर मूल्यांकनकर्ता() विधि को थ्रेड निष्पादन पूर्ण किया जाता है और राइनो इंजन आंतरिक रूप से निष्पादन का प्रबंधन करता है। – Syam

+0

यही कारण है कि मैंने सुझाव दिया कि इसे अपने धागे समूह में रखा जाए; राइनो द्वारा बनाए गए किसी भी अन्य थ्रेड अभी भी उस थ्रेड समूह (या एक बच्चे थ्रेड समूह) में होंगे, इसलिए अब भी उन्हें सभी को _k करना संभव होगा। –

2

एक समाधान की तलाश में किसी और के लिए, ContextFactory के लिए जावाडोक में वर्णन है कि 10 सेकंड से अधिक चल रहा है एक स्क्रिप्ट को रोकने के लिए:

https://github.com/mozilla/rhino/blob/master/src/org/mozilla/javascript/ContextFactory.java

+0

कस्टम ContextFactory दृष्टिकोण शानदार ढंग से काम करता है। यदि आपको जावा से जावाडोक पढ़ने में समस्याएं हैं तो यहां एक HTML संस्करण है: http://www.jarvana.com/jarvana/view/org/mozilla/rhino/1.7R3/rhino-1.7R3-javadoc.jar!/org /mozilla/javascript/ContextFactory.html – kevinjansz

+0

मैं इस के प्रदर्शन प्रभाव और डीबगर विधि के बारे में सोच रहा हूं। कोई विचार? – HRJ

+0

मुझे लगता है कि डीबगर विधि का प्रदर्शन पर कुछ प्रभाव पड़ता है क्योंकि संदर्भ डीबग जानकारी उत्पन्न कर रहा है। कुछ निश्चित निर्देशों को निष्पादित करने के बाद ContextFactory समाधान बस आग लग जाता है। – bigspotteddog

0

मैं एक ExecutorService उपयोग कर एक नया सूत्र में आलेख निष्पादित और समय समाप्त हो गया future.get

ExecutorService executor = Executors.newSingleThreadExecutor(); 

    Future<?> future = executor.submit(threadEvaluation); 

    try { 
     System.out.println("Started.."); 
     future.get(100, TimeUnit.MILLISECONDS); 
     System.out.println("Finished!"); 
    } catch (TimeoutException e) { 
     future.cancel(true); 
     System.out.println("Terminated!"); 
    } 

सूचना है कि इस दृष्टिकोण स्क्रिप्ट पर कार्य धागा बंद नहीं होगा!आदेश को क्रियान्वित करने अपनी स्क्रिप्ट बाधित हो लिए सूचित किया जाएगा धागे के रूप, ऐसा करने के लिए, आपको लगता है कि समय-समय पर इस स्थिति पर नज़र रखता है एक कस्टम ContextFactory बना सकते हैं:

public class InterruptableContextFactory extends ContextFactory { 

    public static boolean initialized = false; 

    public static void init() { 
     if (!initialized) { 
      ContextFactory.initGlobal(new InterruptableContextFactory()); 
      initialized = true; 
     } 
    } 

    @Override 
    protected void observeInstructionCount(Context cx, int instructionCount) { 
     System.out.println(instructionCount + " javascript instructions!"); 
     if (Thread.currentThread().isInterrupted()) { 
      throw new Error("script execution aborted"); 
     } 
    } 

    @Override 
    protected Context makeContext() { 
     Context cx = super.makeContext(); 
     //set a number of instructions here 
     cx.setInstructionObserverThreshold(10000); 
     return cx; 
    } 
} 

किसी भी संदर्भ वस्तु बनाने से पहले, आप अपने आवेदन विन्यस्त करने की जरूरत

try { 
     cx.setOptimizationLevel(9); 
     cx.setInstructionObserverThreshold(10000); 
     ScriptableObject scope = cx.initStandardObjects(); 

     // your code here 

    } catch (Error e) { 
     System.out.println("execution was aborted: " + e.getMessage()); 
    } finally { 
     Context.exit(); 
    } 

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

  • कोई संबंधित समस्या नहीं^_^