public async Task <ActorResponse> SendRemoteActorRequest(ActorRequest request, TimeSpan?timeout = null) { if (request.WorkerActor) { var allStages = await _stageDirectory.GetAllStages(); var stageAddress = allStages.OrderBy(a => Guid.NewGuid()).FirstOrDefault(); return(await SendRemoteActorRequest(stageAddress, request, timeout)); } else { var stageResponse = await _actorDirectory.GetAddress(request.ActorInterface, request.ActorId); if (await _stageDirectory.IsLive(stageResponse.StageId)) { return(await SendRemoteActorRequest(stageResponse.StageId, request, timeout)); } else { return(await SendRemoteActorRequest(null, request, timeout)); } } }
public async Task ReceivedActorRequest(ActorRequest message, string sourceStageId) { if (_localStage == null || !_localStage.Enabled) { //we are inside a client, no point on getting actor requests _exitSemaphore.Release(); return; } if (message.WorkerActor) { await ProcessActorRequestLocally(message, sourceStageId); return; } if (_localStage.CanProcessMessage(message)) { //we already have a local instance await ProcessActorRequestLocally(message, sourceStageId); return; } //query the directory var queryResult = await _actorDirectory.GetAddress(message.ActorInterface, message.ActorId); if (queryResult.Found) { if (queryResult.StageId == _localStage.StageGuid) { //instance already registered on this stage but not active await ProcessActorRequestLocally(message, sourceStageId); return; } else { if (await _stageDirectory.IsLive(queryResult.StageId)) { //proxy request to the right stage var remoteResponse = await _remoteClient.Value.SendRemoteActorRequest(queryResult.StageId, message); if (!message.FireAndForget) { await this.SendActorResponse(sourceStageId, remoteResponse); } } else { //reallocate the actor var newStageId = await _actorDirectory.Reallocate(message.ActorInterface, message.ActorId, queryResult.StageId); //try again await ReceivedActorRequest(message, sourceStageId); } } } else { //reallocate the actor var newStageId = await _actorDirectory.Reallocate(message.ActorInterface, message.ActorId, queryResult.StageId); //try again await ReceivedActorRequest(message, sourceStageId); } }