Ejemplo n.º 1
0
        /// <summary>
        /// The C# worker process is used to execute only one JVM Task. It will exit after the task is finished.
        /// </summary>
        private static void RunSimpleWorker()
        {
            try
            {
                InitializeLogger();
                logger.LogInfo("RunSimpleWorker ...");
                PrintFiles();

                int javaPort = int.Parse(Console.ReadLine()); //reading port number written from JVM
                logger.LogDebug("Port number used to pipe in/out data between JVM and CLR {0}", javaPort);
                Socket socket = InitializeSocket(javaPort);
                TaskRunner taskRunner = new TaskRunner(0, socket, false);
                taskRunner.Run();
            }
            catch (Exception e)
            {
                logger.LogError("RunSimpleWorker failed with exception, will Exit");
                logger.LogException(e);
                Environment.Exit(-1);
            }

            logger.LogInfo("RunSimpleWorker finished successfully");
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Listen to the server socket and accept new TCP connection from JVM side. Then create new TaskRunner instance and
        /// add it to waitingTaskRunners queue.
        /// </summary>
        private void StartDaemonServer(TcpListener listener)
        {
            logger.LogInfo("StartDaemonServer ...");

            bool sparkReuseWorker = false;
            string envVar = Environment.GetEnvironmentVariable("SPARK_REUSE_WORKER"); // this envVar is set in JVM side
            if ((envVar != null) && envVar.Equals("1"))
            {
                sparkReuseWorker = true;
            }

            try
            {
                int trId = 1;
                int workThreadNum = 0;

                while (true)
                {
                    Socket socket = listener.AcceptSocket();
                    logger.LogInfo("Connection accepted for taskRunnerId: {0}", trId);
                    using (NetworkStream s = new NetworkStream(socket))
                    {
                        SerDe.Write(s, trId); // write taskRunnerId to JVM side
                        s.Flush();
                    }
                    TaskRunner taskRunner = new TaskRunner(trId, socket, sparkReuseWorker);
                    waitingTaskRunners.Add(taskRunner);
                    taskRunnerRegistry[trId] = taskRunner;
                    trId++;

                    int taskRunnerNum = taskRunnerRegistry.Count();
                    while (workThreadNum < taskRunnerNum)  // launch new work thread as appropriate
                    {
                        // start threads that do the actual work of running tasks, there are several options here:
                        // Option 1. TPL - Task Parallel Library
                        // Option 2. ThreadPool
                        // Option 3. Self managed threads group
                        // Option 3 is selected after testing in real cluster because it can get the best performance.
                        // When using option 1 or 2, it is observered that the boot time may be as large as 50 ~ 60s.
                        // But it is always less than 1s for option 3. Perhaps this is because TPL and ThreadPool are not
                        // suitable for long running threads.
                        new Thread(FetchAndRun).Start();
                        workThreadNum++;
                    }
                }
            }
            catch (Exception e)
            {
                logger.LogError("StartDaemonServer exception, will exit");
                logger.LogException(e);
                Environment.Exit(-1);
            }
        }
Ejemplo n.º 3
0
        public void Run()
        {
            try
            {
                // start TCP listening server
                var listener = SocketFactory.CreateSocket();
                listener.Listen();

                // get the local port and write it back to JVM side
                IPEndPoint endPoint     = (IPEndPoint)listener.LocalEndPoint;
                int        localPort    = endPoint.Port;
                byte[]     bytes        = SerDe.ToBytes(localPort);
                Stream     outputStream = Console.OpenStandardOutput();
                outputStream.Write(bytes, 0, sizeof(int));

                // can not initialize logger earlier to avoid unwanted stdout ouput
                InitializeLogger();
                logger.LogInfo("Run MultiThreadWorker ...");
                logger.LogDebug("Port number used to pipe in/out data between JVM and CLR {0}", localPort);
                Worker.PrintFiles();

                // start daemon server to listen to socket
                new Thread(() =>
                {
                    StartDaemonServer(listener);
                }).Start();

                // read from JVM via pipe, stop TaskRunner according to instruction from JVM side
                Stream inputStream = Console.OpenStandardInput();
                while (true)
                {
                    int length = inputStream.Read(bytes, 0, sizeof(int));

                    if (length != sizeof(int))
                    {
                        logger.LogError("Read error, length: {0}, will exit", length);
                        Environment.Exit(-1);
                    }
                    int trId = SerDe.ToInt(bytes);
                    if (trId < 0)
                    {
                        // This branch is used in Unit test to stop MultiThreadServer
                        logger.LogInfo("receive negative trId: {0}, will exit", trId);
                        Environment.Exit(0);
                    }
                    else
                    {
                        logger.LogInfo("try to stop taskRunner [{0}]", trId);
                        if (taskRunnerRegistry.ContainsKey(trId))
                        {
                            TaskRunner tr = taskRunnerRegistry[trId];
                            tr.Stop();
                        }
                        else
                        {
                            logger.LogWarn("can't find taskRunner [{0}] in TaskRunnerRegistery. Maybe it has exited already?", trId);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                logger.LogError("RunDaemonWorker exception, will Exit");
                logger.LogException(e);
                Environment.Exit(-1);
            }
        }