public BrokerActor() : base() { // heartbeat actor Become(BehaviorBrokerStart()); // register worker AddBehavior(BehaviorRegisterWorker()); // unregister worker AddBehavior(BehaviorUnregisterWorker()); // process client request AddBehavior(BehaviorProcessClientRequest()); // worker refuse job AddBehavior(new Behavior <IActor, WorkerReadyState, ActorTag> ( (a, s, t) => s == WorkerReadyState.Busy, (a, s, t) => { _workers[a].State = WorkerReadyState.Busy; LogString("Worker {0} can't process request {1}", a.Tag.Key(), t.Key()); IActor worker = FindWorker(); if (worker != null) { _workers[worker].State = WorkerReadyState.Busy; _workers[worker].TimeToLive = 0; worker.SendMessage((IActor)this, t, _requests[t]); LogString("ReProcessing Request {0} on worker {1}", a.Tag.Key(), t.Key()); } else { LogString("Wait for a worker for Request {0}", t.Key()); } } )); // worker finished job AddBehavior(new Behavior <IActor, WorkerReadyState, ActorTag> ( (a, s, t) => s == WorkerReadyState.Idle, (a, s, t) => { _requestProcessed++; _requests.Remove(t); _workers[a].State = WorkerReadyState.Idle; _workers[a].TimeToLive = _ttl; LogString("Request {0} End on worker {1}", t.Key(), a.Tag.Key()); // find a request RequestStatus <T> tagRequest = _requests.Values.FirstOrDefault(v => v.State == RequestState.Unprocessed); if (tagRequest == null) { return; } _workers[a].State = WorkerReadyState.Busy; _workers[a].TimeToLive = 0; tagRequest.State = RequestState.Running; a.SendMessage((IActor)this, tagRequest.Tag, tagRequest.Data); LogString("Processing Request {0} reusing worker {1}", tagRequest.Tag.Key(), a.Tag.Key()); } )); // heartbeatactor AddBehavior(new Behavior <HeartBeatActor, HeartBeatAction> ( (a, h) => { foreach (KeyValuePair <IActor, WorkerStatus> worker in _workers.Where(w => w.Value.TimeToLive < _ttl)) { worker.Key.SendMessage((IActor)this, BrokerAction.Hearbeat); } _ttl++; LogString("Heart Beat Signal, Request Processed {0}", _requestProcessed); } )); // heartbeat answer AddBehavior(new Behavior <IActor, WorkerReadyState>( (a, w) => { WorkerStatus workerState = _workers[a]; workerState.TimeToLive = _ttl; LogString("Answer To HeartBeat from Worker {0}", a.Tag.Key()); })); // start heart beat SendMessage(BrokerAction.Start); }
public BrokerActor() : base() { // heartbeat actor Become(BehaviorBrokerStart()); // register worker AddBehavior(BehaviorRegisterWorker()); // unregister worker AddBehavior(BehaviorUnregisterWorker()); // process client request AddBehavior(new Behavior <T>( (t) => true, (t) => { var requestStatus = new RequestStatus <T>(); requestStatus.Data = t; requestStatus.State = RequestState.Unprocessed; requestStatus.Tag = new ActorTag(); fRequests[requestStatus.Tag] = requestStatus; var worker = FindWorker(); if (worker != null) { fWorkers[worker].State = WorkerReadyState.Busy; fWorkers[worker].TTL = 0; worker.SendMessage((IActor)this, requestStatus.Tag, t); requestStatus.State = RequestState.Running; LogString("Processing Request {0} on worker {1}", requestStatus.Tag.Key(), worker.Tag.Key()); } else { LogString("No available worker for Request {0}", requestStatus.Tag.Key()); } })); // worker refuse job AddBehavior(new Behavior <IActor, WorkerReadyState, ActorTag> ( (a, s, t) => s == WorkerReadyState.Busy, (a, s, t) => { fWorkers[a].State = WorkerReadyState.Busy; LogString("Worker {0} can't process request {1}", a.Tag.Key(), t.Key()); var worker = FindWorker(); if (worker != null) { fWorkers[worker].State = WorkerReadyState.Busy; fWorkers[worker].TTL = 0; worker.SendMessage((IActor)this, t, fRequests[t]); LogString("ReProcessing Request {0} on worker {1}", a.Tag.Key(), t.Key()); } else { LogString("Wait for a worker for Request {0}", t.Key()); } } )); // worker finished job AddBehavior(new Behavior <IActor, WorkerReadyState, ActorTag> ( (a, s, t) => s == WorkerReadyState.Idle, (a, s, t) => { fRequestProcessed++; fRequests.Remove(t); fWorkers[a].State = WorkerReadyState.Idle; fWorkers[a].TTL = fTTL; LogString("Request {0} End on worker {1}", t.Key(), a.Tag.Key()); // find a request var tagRequest = fRequests.Values.FirstOrDefault(v => v.State == RequestState.Unprocessed); if (tagRequest != null) { fWorkers[a].State = WorkerReadyState.Busy; fWorkers[a].TTL = 0; tagRequest.State = RequestState.Running; a.SendMessage((IActor)this, tagRequest.Tag, tagRequest.Data); LogString("Processing Request {0} reusing worker {1}", tagRequest.Tag.Key(), a.Tag.Key()); } } )); // heartbeatactor AddBehavior(new Behavior <HeartBeatActor, HeartBeatAction> ( (a, h) => { foreach (var worker in fWorkers.Where(w => w.Value.TTL < fTTL)) { worker.Key.SendMessage((IActor)this, BrokerAction.Hearbeat); } fTTL++; LogString("Heart Beat Signal, Request Processed {0}", fRequestProcessed); } )); // heartbeat answer AddBehavior(new Behavior <IActor, WorkerReadyState>( (a, w) => { var workerState = fWorkers[a]; workerState.TTL = fTTL; LogString("Answer To HeartBeat from Worker {0}", a.Tag.Key()); })); // start heart beat SendMessage(BrokerAction.Start); }