예제 #1
0
파일: WorkerAgent.cs 프로젝트: mehrta/Quax
        private bool SendResultToJobServer(Job j, out bool errorInReadingOutputFile)
        {
            const int HEADER_FLAGS_FIELD_SIZE        = 1; // 1 Byte
            const int HEADER_PAYLOAD_SIZE_FIELD_SIZE = 4; // 4 Byte
            const int HEADER_WORKER_ID_FIELD_SIZE    = 2; // 2 Byte
            const int HEADER_JOB_ID_FIELD_SIZE       = 8; // 8 Byte
            const int HEADER_PAYLOAD_START_INDEX     = HEADER_FLAGS_FIELD_SIZE + HEADER_PAYLOAD_SIZE_FIELD_SIZE +
                                                       HEADER_WORKER_ID_FIELD_SIZE + HEADER_JOB_ID_FIELD_SIZE;

            byte[] message     = null;
            long   messageSize = 0;
            bool   jobOutputFileReadSuccessfully = true;
            uint   jobOutputFileLength           = 0;

            #region Read Job's output file
            System.IO.FileStream        fs             = null;
            ErrorInReadingJobOutputFile fileReadErrLog = null;
            try {
                // Open Job's result file for reading
                fs = System.IO.File.OpenRead(j.OutputFileName);

                // allocate memory for message
                jobOutputFileLength = (uint)fs.Length;
                messageSize         = HEADER_FLAGS_FIELD_SIZE + HEADER_PAYLOAD_SIZE_FIELD_SIZE + HEADER_WORKER_ID_FIELD_SIZE +
                                      HEADER_JOB_ID_FIELD_SIZE + jobOutputFileLength;
                message = new byte[messageSize];
                //

                // Read file and close it
                fs.Read(message, HEADER_PAYLOAD_START_INDEX, (int)jobOutputFileLength);
                errorInReadingOutputFile = false;
            }
            catch (System.IO.FileNotFoundException fileNotFoundExcp) {
                jobOutputFileReadSuccessfully = false;
                fileReadErrLog              = new WorkerAgent.ErrorInReadingJobOutputFile();
                fileReadErrLog.Job          = j;
                fileReadErrLog.Message      = "Job's output file not found.";
                fileReadErrLog.ErrorMessage = fileNotFoundExcp.Message;
                errorInReadingOutputFile    = true;
                EventExtensions.Raise(NewLogItem, new[] { fileReadErrLog });
            }
            catch (Exception e) {
                jobOutputFileReadSuccessfully = false;
                fileReadErrLog              = new WorkerAgent.ErrorInReadingJobOutputFile();
                fileReadErrLog.Job          = j;
                fileReadErrLog.Message      = "Error in reading job's output file.";
                fileReadErrLog.ErrorMessage = e.Message;
                errorInReadingOutputFile    = true;
                EventExtensions.Raise(NewLogItem, new[] { fileReadErrLog });
            }
            finally {
                if (fs != null)
                {
                    fs.Close();
                }
            }
            #endregion

            if (!jobOutputFileReadSuccessfully)
            {
                return(false);
            }

            #region Send job result(message) to the job server
            // Set Header's fields of the message
            byte[] payloadSizeBytes = new byte[4]; // UInt32
            byte[] workerIDBytes    = new byte[2]; // UInt16
            byte[] jobIDBytes       = new byte[8]; // UInt64

            // Flags
            message[0] = 0; // This field is reserved for future use.

            // Payload Size, UInt32
            payloadSizeBytes = BitConverter.GetBytes(jobOutputFileLength);
            for (int i = 0; i < 4; i++)
            {
                message[i + HEADER_FLAGS_FIELD_SIZE] = payloadSizeBytes[i];
            }

            // Worker ID, UInt16
            workerIDBytes = BitConverter.GetBytes(ID);
            for (int i = 0; i < 2; i++)
            {
                message[i + HEADER_FLAGS_FIELD_SIZE + HEADER_PAYLOAD_SIZE_FIELD_SIZE] = workerIDBytes[i];
            }

            // JobID, UInt64
            jobIDBytes = BitConverter.GetBytes(j.ID);
            for (int i = 0; i < 8; i++)
            {
                message[i + HEADER_FLAGS_FIELD_SIZE + HEADER_PAYLOAD_SIZE_FIELD_SIZE + HEADER_WORKER_ID_FIELD_SIZE] = jobIDBytes[i];
            }

            // Try "AttemptsToSendResult" times to send the message
            bool          successfullySent = false;
            TcpClient     client           = new TcpClient();
            NetworkStream netStream        = null;

            for (int i = 1; (i <= AttemptsToSendResult) && (!successfullySent); i++)
            {
                try {
                    client.Connect(new IPEndPoint(JobServerIPAddress, JobServerDataChannelPortNumber));
                    netStream = client.GetStream();
                    netStream.Write(message, 0, (int)messageSize);
                    successfullySent = true;

                    // Generate log
                    WorkerAgent.JobResultSentLog log = new JobResultSentLog();
                    log.Job     = j;
                    log.Message = "Job's output file sent to the job server.";
                    EventExtensions.Raise(NewLogItem, new[] { log });
                }
                catch (Exception e) {
                    successfullySent = false;
                    WorkerAgent.ErrorInConnectingToJobServerLog log = new ErrorInConnectingToJobServerLog();
                    log.Message      = "[ Attempt " + (i).ToString() + " ]   Could not connect to the job server to transfer the results.";
                    log.ErrorMessage = e.Message;
                    EventExtensions.Raise(NewLogItem, new[] { log });
                }

                if ((!successfullySent) && (i < AttemptsToSendResult))
                {
                    // if an error has occured in sending, Wait 1 second and then try to send again
                    System.Threading.Thread.Sleep(3000);
                }
            }

            if (netStream != null)
            {
                netStream.Close();
            }
            client.Close();
            #endregion

            return(successfullySent);
        }
예제 #2
0
            // Methods
            public bool RegisterWorker(UInt16 WorkerID, int DataChannelPortNumber, int ControlChannelPortNumber)
            {
                const int MESSAGE_SIZE = 7;
                //const int REPLY_CODE_FAILURE = 0;
                const int REPLY_CODE_SUCCESSFULLY_REGISTERED           = 2;
                const int REPLY_CODE_REGISTRATION_FAILED_DUPLICATE_ID_ = 3;

                bool          registered;
                TcpClient     client = new TcpClient();
                NetworkStream netStream;

                byte[] message = new byte[MESSAGE_SIZE];
                byte[] reply   = new byte[1];

                #region set message fields
                byte[] workerIDBytes, dataChannelPortNumberBytes, controlChannelPortNumberBytes;

                // Code = 1
                message[0] = 1;

                // Worker ID
                workerIDBytes = BitConverter.GetBytes(WorkerID);
                message[1]    = workerIDBytes[0];
                message[2]    = workerIDBytes[1];

                // DataChannelPortNumber
                dataChannelPortNumberBytes = BitConverter.GetBytes((UInt16)DataChannelPortNumber);
                message[3] = dataChannelPortNumberBytes[0];
                message[4] = dataChannelPortNumberBytes[1];

                // ControlChannelPortNumberBytes
                controlChannelPortNumberBytes = BitConverter.GetBytes((UInt16)ControlChannelPortNumber);
                message[5] = controlChannelPortNumberBytes[0];
                message[6] = controlChannelPortNumberBytes[1];
                #endregion

                // Generate WorkerRegisterationStartedLog log
                WorkerRegisterationStartLog registerationStartedlog = new WorkerRegisterationStartLog();
                registerationStartedlog.Message = "Registering worker...";
                NewLogItem(registerationStartedlog);

                // Connect to job server and send message
                registered = false;
                try {
                    client.Connect(JobServerControlUnit);
                    netStream             = client.GetStream();
                    netStream.ReadTimeout = 3000;  // Wait 3 seconds for reply from server

                    netStream.Write(message, 0, MESSAGE_SIZE);
                    netStream.Read(reply, 0, 1);

                    if (reply[0] == REPLY_CODE_SUCCESSFULLY_REGISTERED)
                    {
                        registered = true;

                        // Generate WorkerRegisterdLog log
                        WorkerRegisterdLog log = new WorkerRegisterdLog();
                        log.Message = "Worker registerd.";
                        NewLogItem(log);
                    }
                    else if (reply[0] == REPLY_CODE_REGISTRATION_FAILED_DUPLICATE_ID_)
                    {
                        // Generate WorkerRegisterationFailedLog log
                        WorkerRegisterationFailedLog log = new WorkerRegisterationFailedLog();
                        log.Message = "Registeration failed. a worker with ID=" + WorkerID.ToString() + " is currently registered. please change Worker ID.";
                        NewLogItem(log);
                    }
                }
                catch (Exception e) {
                    // Generate ErrorInConnectingToJobServerLog log
                    ErrorInConnectingToJobServerLog log = new ErrorInConnectingToJobServerLog();
                    log.ErrorMessage = e.Message;
                    log.Message      = "Error in connecting to job server.";
                    NewLogItem(log);
                }
                finally {
                    client.Close();
                }

                return(registered);
            }