Example #1
0
        public void Stop()
        {
            Log log;

            try {
                IsListening = false; // This line should comes before "_listener.stop()"
                _listener.Stop();

                // Generate Log
                log         = new WorkerStoppedLog();
                log.Message = "Worker stopped.";
            }
            catch (Exception e) {
                // Generate Log
                log         = new WorkerCouldNotStopLog();
                log.Message = "Worker could not stop.";
                ((WorkerCouldNotStopLog)log).ErrorMessage = e.Message;
            }

            // Raise "NewLogItem" event
            EventExtensions.Raise(NewLogItem, new[] { log });
        }
Example #2
0
        private void AcceptConnectionCallBack(IAsyncResult ar)
        {
            byte[] message      = null; // buffer
            byte   numberOfJobs = 0;
            byte   flags;
            uint   payloadSize;
            bool   isLittleEndianArchitecture;

            // Accept Connection
            TcpClient client;

            // After invoking TcpListener.Stop(), this method is invoked and we must return from this method
            // if IsListening is false.
            if (IsListening)
            {
                client = _listener.EndAcceptTcpClient(ar);
            }
            else
            {
                return;
            }

            #region Start reciving data from network and store it in buffer

            const int     HEADER_JOB_ID_FIELD_SIZE = 8;                 // 8 Byte
            const int     HEADER_JOB_EXECUTABLE_ADDRESS_FIELD_SIZE = 4; // 4 Byte
            const int     HEADER_JOB_INPUT_ADDRESS_FIELD_SIZE      = 4; // 4 Byte
            const int     JOB_HEADER_SIZE         = HEADER_JOB_ID_FIELD_SIZE + HEADER_JOB_EXECUTABLE_ADDRESS_FIELD_SIZE + HEADER_JOB_INPUT_ADDRESS_FIELD_SIZE;
            NetworkStream netStream               = null;
            bool          dataRecivedSuccessfully = true;

            try {
                netStream = client.GetStream();

                // Reads field "Flags"
                flags = (byte)netStream.ReadByte();
                isLittleEndianArchitecture = (flags == 0) ? true : false;

                // Reads field "Number Of Jobs"
                numberOfJobs = (byte)netStream.ReadByte();

                // Reads field "Payload Size"
                byte[] payloadSizeBytes = new byte[4];
                netStream.Read(payloadSizeBytes, 0, 4);
                if (!isLittleEndianArchitecture)
                {
                    payloadSizeBytes.Reverse();
                }
                payloadSize = BitConverter.ToUInt32(payloadSizeBytes, 0);
                //

                // Allocate memory for the rest of message (without fileds "Flags", "Number of jobs" and "Payload Size")
                // And read rest of the message from the NetworkStream
                int messageSize = (numberOfJobs * JOB_HEADER_SIZE) + (int)payloadSize;
                message = new byte[messageSize];
                netStream.Read(message, 0, messageSize);
            }
            catch {
                dataRecivedSuccessfully = false;
            }
            finally {
                if (netStream != null)
                {
                    netStream.Close();
                }
                if (client != null)
                {
                    client.Close();
                }
            }

            // Start listening for new connections
            try {
                //_listener.Start(1);
                _listener.BeginAcceptTcpClient(AcceptConnectionCallBack, _listener);
            }
            catch {
                // Generate WorkerCouldNotStartLog log
                WorkerStoppedLog log = new WorkerStoppedLog();
                log.Message = "Worker could not continue to listen for new jobs, so it has stopped.";
                EventExtensions.Raise(NewLogItem, new[] { log });
            }

            #endregion

            #region Create job objects and save theam to the "JobsDirectoryName" directory

            // numberOfJobs = 1
            List <Job> recivedJobs = new List <Job>(10);
            if (dataRecivedSuccessfully)
            {
                for (int i = 0; i < numberOfJobs; i++)
                {
                    #region Create job object
                    Job    newJob = new Job();
                    UInt32 jobExecutableStartLocation;
                    UInt32 jobInputStartLocation;

                    // ID
                    newJob.ID = BitConverter.ToUInt64(message, 0);

                    // InputFileName
                    StringBuilder filename = new StringBuilder(50);
                    DateTime      now      = DateTime.Now;
                    Random        rnd      = new Random();

                    filename.Append(JobsDirectoryName);
                    filename.Append("\\job");
                    filename.Append(newJob.ID.ToString());
                    filename.Append("_");
                    filename.Append(now.Hour.ToString("D2"));
                    filename.Append(now.Minute.ToString("D2"));
                    filename.Append(now.Second.ToString("D2"));
                    filename.Append("_");
                    filename.Append(rnd.Next(1000000).ToString("D6"));

                    newJob.InputFileName = filename.ToString() + ".in";

                    // OutputFileName
                    newJob.OutputFileName = filename.ToString() + ".out";

                    // ExecuteableFileName
                    newJob.ExecuteableFileName = filename.ToString() + ".exe";

                    #endregion

                    #region Write job's Executable and input files to disk
                    jobExecutableStartLocation  = BitConverter.ToUInt32(message, 8);  // in payload address space
                    jobInputStartLocation       = BitConverter.ToUInt32(message, 12); // in payload address space
                    jobExecutableStartLocation += 16;
                    jobInputStartLocation      += 16;
                    newJob.ExecutableFileLength = jobInputStartLocation - jobExecutableStartLocation;
                    newJob.InputFileLength      = (UInt32)message.Length - newJob.ExecutableFileLength - JOB_HEADER_SIZE;

                    System.IO.FileStream fsExe   = null;
                    System.IO.FileStream fsInput = null;
                    try {
                        // Create "jobs directory" if it is not exists
                        if (!System.IO.Directory.Exists(JobsDirectoryName))
                        {
                            System.IO.Directory.CreateDirectory(JobsDirectoryName);
                        }

                        // Create job's executable file
                        fsExe = System.IO.File.Create(newJob.ExecuteableFileName);
                        fsExe.Write(message, (int)jobExecutableStartLocation, (int)newJob.ExecutableFileLength);

                        // Create job's input file
                        fsInput = System.IO.File.Create(newJob.InputFileName);
                        fsInput.Write(message, (int)jobInputStartLocation, (int)newJob.InputFileLength);

                        // Add jobs to the jobs queue
                        lock (_jobsQueue) {
                            _jobsQueue.Enqueue(newJob);
                        }

                        // Add jobs to the recieved jobs list
                        recivedJobs.Add(newJob);
                    }
                    catch (Exception e) {
                        // Error in writing jobs to the disk
                        // Generate log and Raise "NewLogItem" event
                        WorkerAgent.ErrorInWritingJobToDiskLog log = new WorkerAgent.ErrorInWritingJobToDiskLog();
                        log.Job          = newJob;
                        log.Message      = "Could not write the job to the jobs directory, please verify jobs directory.";
                        log.ErrorMessage = e.Message;
                        EventExtensions.Raise(NewLogItem, new[] { log });
                    }
                    finally {
                        if (fsExe != null)
                        {
                            fsExe.Close();
                        }
                        if (fsInput != null)
                        {
                            fsInput.Close();
                        }
                    }
                    #endregion
                }
            }

            // Generate Log
            WorkerAgent.JobsRecivedLog recivelog = new WorkerAgent.JobsRecivedLog();
            ((WorkerAgent.JobsRecivedLog)recivelog).Jobs = recivedJobs.ToArray();
            recivelog.Message = "A batch of jobs recieved.";

            // Raise "NewLogItem" event
            EventExtensions.Raise(NewLogItem, new[] { recivelog });

            #endregion
        }