Example #1
0
        static ActorAssignment GetAssignment(Actor actor, bool prepareTestData = true)
        {
            ActorAssignment actorEntity = null;

            try
            {
                // Create the CloudTable object that represents the "topology" table.
                CloudTable table = Environment.GetTable("topology");

                // $TEST: prepare test data so that the code can be executed in Azure Emulator
                if (prepareTestData)
                {
                    Environment.PrepareTestData(actor);
                }

                // Create a retrieve operation that takes a customer entity.
                TableOperation retrieveOperation = TableOperation.Retrieve <ActorAssignment>(ActorAssignment.Key, actor.Id.ToString());

                // Execute the retrieve operation.
                TableResult retrievedResult = table.Execute(retrieveOperation);

                // Get Assignment
                if (retrievedResult.Result != null)
                {
                    actorEntity = (ActorAssignment)retrievedResult.Result;
                }
            }
            catch (Exception e)
            {
                Trace.TraceInformation("Failed to get assignment:" + e.Message);
                RoundLogger.Current.Log(e.StackTrace);
            }

            return(actorEntity);
        }
Example #2
0
        // The thread procedure performs the independent task
        static void ThreadProc(Object stateInfo)
        {
            ActorAssignment assignment = null;
            Actor           actor      = (Actor)stateInfo;

            Trace.TraceInformation("Deployment {0} Actor {1} is Initialized.", actor.DeploymentId, actor.Id);

            while (true)
            {
                RoundLogger.Current.SetSceneId(actor);

                if (actor.State == ActorState.NewBorn)
                {
                    // Needs to contact central to get new assignment

                    // if there is an assignment then
                    assignment = GetAssignment(actor);
                    if (assignment != null && !string.IsNullOrWhiteSpace(assignment.Name))
                    {
                        actor.State = ActorState.Working;
                        RoundLogger.Current.Log("Get Assignment and switch State to Working.");
                    }
                    else
                    {
                        RoundLogger.Current.Log("Waiting for assignment.");

                        // Let's check assignment 10 seconds later
                        Thread.Sleep(10000);
                    }
                }
                else if (actor.State == ActorState.Working)
                {
                    RoundLogger.Current.Log("Working on the assignment");

                    try
                    {
                        // $TODO: need to fetch package for new assignment
                        (new ActorExecution(actor, assignment)).Run();
                    }
                    catch (Exception e)
                    {
                        actor.State        = ActorState.Error;
                        actor.ErrorMessage = e.Message;
                        actor.ErrorStack   = e.StackTrace;

                        RoundLogger.Current.Log("Failed to execute topology:" + e.Message);
                        RoundLogger.Current.Log(e.StackTrace);
                    }
                }
                else if (actor.State == ActorState.Error)
                {
                    RoundLogger.Current.Log("The Actor is shutdown due to Error State.");
                    break;
                }

                actor.HeartBeat = DateTime.UtcNow;
            }
        }
Example #3
0
 public ActorExecution(Actor actor, ActorAssignment assignment)
 {
     this.actor      = actor;
     this.assignment = assignment;
 }
Example #4
0
        /// <summary>
        /// - Send Heartbeat to Central
        ///     - Service Up/Down
        ///     - Actor State
        /// - Kill Error Actor and Keep Actor Number;
        /// </summary>
        internal void Run()
        {
            do
            {
                Thread.Sleep(15000);

                Trace.TraceInformation("Service Maintain {0}", RoleEnvironment.DeploymentId);

                CloudTable table = Environment.GetTable("topology");

                lock (LockObject)
                {
                    IList <Guid> errorActors = new List <Guid>();

                    // Remove Actor which in Error State, and fork a new one
                    foreach (Guid id in this.actors.Keys)
                    {
                        // NOTE: we still give Actor in Error State the last chance to report its state.
                        if (this.actors[id].State == ActorState.Error)
                        {
                            // Cannot modify this.actors in foreach
                            errorActors.Add(id);
                        }

                        try
                        {
                            if (this.actors[id].State == ActorState.Working)
                            {
                                var ass = GetAssignment(this.actors[id], false);

                                if (ass != null)
                                {
                                    if (string.Equals("Kill", ass.Operation, StringComparison.OrdinalIgnoreCase))
                                    {
                                        // I didn't lock this Actor considering there is no state transition from Working to non Error.
                                        this.actors[id].State = ActorState.Error;
                                    }
                                }
                            }

                            ActorAssignment assignment = new ActorAssignment(id)
                            {
                                HeartBeat = this.actors[id].HeartBeat, State = this.actors[id].State.ToString(), ErrorMessage = this.actors[id].ErrorMessage, ErrorStack = this.actors[id].ErrorStack
                            };
                            TableOperation mergeOperation  = TableOperation.InsertOrMerge(assignment);
                            TableResult    retrievedResult = table.Execute(mergeOperation);

                            Trace.TraceInformation("Actor {0} updated HeartBeat", id);
                        }
                        catch (Exception e)
                        {
                            Trace.TraceInformation("Actor {0} failed to update HeartBeat due to {1}", id, e.Message);
                        }
                    }

                    foreach (Guid id in errorActors)
                    {
                        this.actors.Remove(id);
                        this.ForkNewActor();
                    }
                }
            }while (true);
        }