Exemplo n.º 1
0
        private void Process()
        {
            Pipe.WaitForConnection();
            var msgWatch = new Stopwatch();

            while (true)
            {
                Tuple <Protocol.Request, TaskCompletionSource <Protocol.Response>, JavaEditor> item = null;
                lock (WorkItems)
                {
                    if (WorkItems.Count == 0)
                    {
                        Thread.Sleep(100); // trottle down
                        continue;
                    }

                    // Dequeue next item
                    while (true)
                    {
                        item = WorkItems.Dequeue();
                        // Peek at the queue to see if the LIFO request was invalidated by a newer request of the same type
                        if (WorkItems.Count != 0 &&
                            LIFORequests.Contains(item.Item1.requestType) &&
                            WorkItems.Any(x => x.Item1.requestType == item.Item1.requestType))
                        {
                            item.Item2.SetCanceled();
                            continue; // There is another request in the queue of the same type; will ignore this one
                        }
                        break;
                    }
                }

                try
                {
                    Telemetry.Client.Get().TrackEvent(
                        "App.MessageSend",
                        new Dictionary <string, string> {
                        { "Protocol.RequestType", item.Item1.requestType.ToString() }
                    },
                        null);

                    if (item.Item3 != null)
                    {
                        item.Item3.Fire_OperationStarted(item.Item1);
                    }

                    msgWatch.Restart();
                    Pipe.WriteMessage(item.Item1);
                    var response = Pipe.ReadMessage();
                    msgWatch.Stop();

                    if (item.Item3 != null)
                    {
                        item.Item3.Fire_OperationCompleted(item.Item1, response);
                    }

                    if (response != null)
                    {
                        Telemetry.Client.Get().TrackEvent(
                            "App.MessageReceived",
                            new Dictionary <string, string> {
                            { "Protocol.ResponseType", response.responseType.ToString() }
                        },
                            null);
                    }

                    if (response != null &&
                        response.responseType == Protocol.Response.ResponseType.FileParseStatus &&
                        response.fileParseResponse.status == false)
                    {
                        // Parse failed; time to shutdown the server
                        // Clear queue
                        lock (WorkItems)
                        {
                            while (WorkItems.Count != 0)
                            {
                                var citem = WorkItems.Dequeue();
                                citem.Item2.SetCanceled();
                            }
                        }

                        // Notify editors and other listeners that the server is about to go down
                        if (TerminatedAbnormally != null)
                        {
                            TerminatedAbnormally(this, response);
                        }

                        // Exit loop
                        break;
                    }

                    Telemetry.Client.Get().TrackMetric("App.Metric.MessageResponse",
                                                       msgWatch.ElapsedMilliseconds, 1, msgWatch.ElapsedMilliseconds, msgWatch.ElapsedMilliseconds,
                                                       new Dictionary <string, string> {
                        { "Protocol.RequestType", item.Item1.requestType.ToString() }
                    });

                    item.Item2.SetResult(response);
                }
                catch (IOException e)
                {
                    item.Item2.SetException(e);

                    Telemetry.Client.Get().TrackException(e, new Dictionary <string, string> {
                        { "Protocol.RequestType", item.Item1.requestType.ToString() }
                    }, null);
                }

                // If "bye", exit the thread since the child process will exit anyway
                if (item.Item1.requestType == Protocol.Request.RequestType.Bye)
                {
                    break; // will exit thread
                }
            }

            if (JavaPkgSrv != null)
            {
                JavaPkgSrv.Close();
            }
            Pipe.Disconnect();
            Pipe.Dispose();
        }