示例#1
0
        /// <summary>
        /// Start a web socket server on a different thread, modifying
        /// the given interpreter to use it.
        /// </summary>
        /// <param name="current">Current interpreter</param>
        public static Thread WSServeThread(Interpreter current)
        {
            var ws            = new Grace.Execution.WebSocketServer();
            var wss           = ws.Start();
            var runningThread = Thread.CurrentThread;
            var runningSink   = new WSOutputSink(wss);

            current.RPCSink   = runningSink;
            wss.JsonReceived += (o, e) => {
                var je   = (JsonWSEvent)e;
                var root = je.Root;
                var md   = root.XPathSelectElement("//mode");
                var mode = md.Value;
                if (mode == "stop")
                {
                    Console.WriteLine("Program stopped on remote end.");
                    runningSink.Stop();
                    runningSink.HardStop();
                    wss.Stop();
                    WebSocketEndpoint.Stop();
                    return;
                }
                else if (mode == "response")
                {
                    processResponse(root);
                    return;
                }
                else if (mode == "callback")
                {
                    if (runningThread != null)
                    {
                        processCallback(root, runningSink);
                    }
                    return;
                }
                else if (mode == "ack")
                {
                    return;
                }
                else
                {
                    Console.WriteLine("unknown mode " + mode);
                }
            };
            var thread = new Thread(() => {
                wss.Run();
            });

            thread.Start();
            return(thread);
        }
示例#2
0
        private static int replyParseTree(ParseNode module,
                                          string modname,
                                          WSOutputSink sink)
        {
            Action <XmlDocument, XmlElement> handler = (doc, parent) =>
            {
                var mod = doc.CreateElement("module");
                var vis = new ParseTreeJSONVisitor(doc, mod);
                parent.AppendChild(module.Visit(vis));
            };

            sink.SendData("parse-tree", modname, handler);
            return(0);
        }
示例#3
0
        private static void processCallback(XElement root,
                                            WSOutputSink sink)
        {
            var blockEl = root.XPathSelectElement("//block");

            if (blockEl == null)
            {
                return;
            }
            int blockID;

            int.TryParse(blockEl.Value, out blockID);
            var argsEl   = root.XPathSelectElement("//args");
            var argsEnum = argsEl.XPathSelectElements("//item");
            var args     = new object[argsEnum.Count()];
            int i        = 0;

            foreach (var arg in argsEnum)
            {
                args[i] = objectFromElement(arg);
            }
            sink.ReceiveCallback(blockID, args);
        }
示例#4
0
        private static int runModule(string code, string modname,
                                     string mode, WSOutputSink sink)
        {
            var interp = new Interpreter(sink);

            ErrorReporting.SetSink(new OutputSinkWrapper(Console.Error));
            interp.RPCSink = sink;
            interp.AddModuleRoot(Path.GetFullPath("."));
            interp.FailedImportHook = loadCachedModule;
            interp.LoadPrelude();
            Parser    parser = new Parser(modname, code);
            ParseNode module;

            try
            {
                module = parser.Parse();
                ExecutionTreeTranslator ett = new ExecutionTreeTranslator();
                Node eModule = ett.Translate(module as ObjectParseNode);
                sink.SendEvent("build-succeeded", modname);
                if (mode == "build")
                {
                    return(0);
                }
                interp.EnterModule(modname);
                try
                {
                    eModule.Evaluate(interp);
                }
                catch (GraceExceptionPacketException ex)
                {
                    sink.SendRuntimeError(ex.ExceptionPacket.Description,
                                          ex.ExceptionPacket.StackTrace);
                }
            }
            catch (StaticErrorException ex)
            {
                sink.SendStaticError(ex.Code, ex.Module, ex.Line,
                                     ex.Message);
            }
            catch (ThreadAbortException)
            {
                throw;
            }
            catch (WebSocketClosedException)
            {
                return(0);
            }
            catch (Exception ex)
            {
                System.Console.Error.WriteLine(
                    "An internal error occurred. "
                    + "Debugging information follows.");
                System.Console.Error.WriteLine("Runtime version: "
                                               + Interpreter.GetRuntimeVersion());
                System.Console.Error.WriteLine(ex);
                System.Console.Error.WriteLine(ex.StackTrace);
                System.Console.Error.WriteLine(
                    "\nAn internal error occurred. "
                    + "This is a bug in the implementation.");
            }
            sink.SendEvent("execution-complete", modname);
            return(0);
        }
示例#5
0
        /// <summary>
        /// Start a WebSocket server.
        /// </summary>
        public static int WSServe()
        {
            var          ws            = new Grace.Execution.WebSocketServer();
            var          wss           = ws.Start();
            Thread       runningThread = null;
            WSOutputSink runningSink   = null;

            while (true)
            {
                wss.JsonReceived += (o, e) => {
                    var je   = (JsonWSEvent)e;
                    var root = je.Root;
                    var md   = root.XPathSelectElement("//mode");
                    var mode = md.Value;
                    if (mode == "stop")
                    {
                        if (runningThread != null)
                        {
                            runningSink.Stop();
                            runningThread.Abort();
                            runningThread = null;
                            runningSink   = null;
                        }
                        return;
                    }
                    else if (mode == "response")
                    {
                        processResponse(root);
                        return;
                    }
                    else if (mode == "callback")
                    {
                        if (runningThread != null)
                        {
                            processCallback(root, runningSink);
                        }
                        return;
                    }
                    else if (mode == "ack")
                    {
                        return;
                    }
                    else if (mode != "build" && mode != "run")
                    {
                        return;
                    }
                    var cn      = root.XPathSelectElement("//code");
                    var mn      = root.XPathSelectElement("//modulename");
                    var code    = cn.Value;
                    var modname = mn.Value;
                    moduleCode[modname] = code;
                    var sink = new WSOutputSink(wss);
                    runningSink = sink;
                    var thread = new Thread(() => {
                        var startSent     = wss.SentFrames;
                        var startReceived = wss.ReceivedFrames;
                        var startTime     = DateTime.Now;
                        try
                        {
                            runModule(code, modname, mode, sink);
                            log("Module " + modname
                                + " completed " + mode + ".");
                            runningThread = null;
                            summarise(wss, startSent, startReceived,
                                      DateTime.Now - startTime);
                        }
                        catch (WebSocketClosedException)
                        {
                            log("Lost WebSocket connection "
                                + "while running module " + modname
                                + ".");
                            runningThread = null;
                            summarise(wss, startSent, startReceived,
                                      DateTime.Now - startTime);
                        }
                        catch (ThreadAbortException)
                        {
                            log("Execution of " + modname
                                + " aborted.");
                            Thread.ResetAbort();
                            summarise(wss, startSent, startReceived,
                                      DateTime.Now - startTime);
                        }
                    });
                    runningThread = thread;
                    log("Spawning thread to " + mode + " "
                        + modname + "...");
                    thread.Start();
                };
                wss.Run();
                wss = ws.Next();
            }
        }