/// <summary> /// Signal that we've received a ping from a neighbor /// </summary> /// <param name="region"></param> private void HandleNeighborPing(SimpleRegionInfo region) { bool newNeighbor = false; KnownNeighborRegion neighbor; lock (_knownNeighbors) { if (_knownNeighbors.TryGetValue(region.RegionHandle, out neighbor)) { neighbor.LastPingReceivedOn = Util.GetLongTickCount(); } else { newNeighbor = true; neighbor = new KnownNeighborRegion { LastPingReceivedOn = Util.GetLongTickCount(), RegionInfo = region }; _knownNeighbors.Add(neighbor.RegionInfo.RegionHandle, neighbor); } } if (newNeighbor) { TriggerNeighborStateChange(region, NeighborStateChangeType.NeighborUp); } TriggerNeighborStateChange(region, NeighborStateChangeType.NeighborPing); }
/// <summary> /// Signal that a neighbor has come up /// </summary> /// <param name="region">The region information</param> private void HandleNeighborUp(SimpleRegionInfo region) { var newNeighbor = new KnownNeighborRegion { LastPingReceivedOn = Util.GetLongTickCount(), RegionInfo = region }; lock (_knownNeighbors) { _knownNeighbors[region.RegionHandle] = newNeighbor; } TriggerNeighborStateChange(region, NeighborStateChangeType.NeighborUp); }
private void KillNeighborOnUpMessageFailure(KnownNeighborRegion neighbor, MessageType type) { //if this is an "up" message, consider the region crashed and remove it from neighbors if (type == MessageType.Up) { lock (_knownNeighbors) { _knownNeighbors.Remove(neighbor.RegionInfo.RegionHandle); _doaRegions.Add(neighbor.RegionInfo.RegionHandle); } } }
/// <summary> /// Begins a series of async calls to refresh neighbor regions from storage. This should be /// called only when we're first coming on line /// </summary> /// <remarks> /// Will throw exceptions if the list can not be loaded /// </remarks> public async Task RefreshNeighborsFromStorage() { Task<List<SimpleRegionInfo>> neighborsTask = _scene.CommsManager.GridService.RequestNeighbors2Async( _scene.RegionInfo.RegionLocX, _scene.RegionInfo.RegionLocY, MAX_DRAW_DISTANCE); await neighborsTask; Dictionary<ulong, KnownNeighborRegion> knownNeighbors = new Dictionary<ulong, KnownNeighborRegion>(); foreach (var neighbor in neighborsTask.Result) { var region = new KnownNeighborRegion { LastPingReceivedOn = Util.GetLongTickCount(), RegionInfo = neighbor }; knownNeighbors.Add(region.RegionInfo.RegionHandle, region); } //atomic swapout _knownNeighbors = knownNeighbors; _timeNeighborsInitiallyQueried = Util.GetLongTickCount(); return; }
private async Task<bool> DoRegionAsyncCall(HttpWebRequest req, KnownNeighborRegion neighbor, MessageType type, byte[] body) { try { using (System.IO.Stream reqStream = await req.GetRequestStreamAsync()) { await reqStream.WriteAsync(body, 0, body.Length); } } catch (Exception e) { _log.ErrorFormat("[REGIONMANAGER]: Could not post request for {0} to region {1} at {2}: {3}", type, neighbor.RegionInfo.RegionHandle, Util.RegionHandleToLocationString(neighbor.RegionInfo.RegionHandle), e.Message); KillNeighborOnUpMessageFailure(neighbor, type); return false; } try { using (WebResponse response = await req.GetResponseAsync(NEIGHBOR_HANDLER_TIMEOUT)) { //we dont do anything with the response } } catch (Exception e) { _log.ErrorFormat("[REGIONMANAGER]: Unable to read response to {0} for region {1} at {2}: {3}", type, neighbor.RegionInfo.RegionHandle, Util.RegionHandleToLocationString(neighbor.RegionInfo.RegionHandle), e.Message); KillNeighborOnUpMessageFailure(neighbor, type); return false; } return true; }