private static void GetValidVideoRecursive(IProvider prov, SVR_GroupFilter f, int userid, Directory pp) { List <SVR_GroupFilter> gfs = RepoFactory.GroupFilter.GetByParentID(f.GroupFilterID) .Where(a => a.GroupsIds.ContainsKey(userid) && a.GroupsIds[userid].Count > 0) .ToList(); foreach (SVR_GroupFilter gg in gfs.Where(a => (a.FilterType & (int)GroupFilterType.Directory) == 0)) { if (gg.GroupsIds.ContainsKey(userid)) { HashSet <int> groups = gg.GroupsIds[userid]; if (groups.Count != 0) { foreach (int grp in groups.Randomize(f.GroupFilterID)) { SVR_AnimeGroup ag = RepoFactory.AnimeGroup.GetByID(grp); Video v = ag.GetPlexContract(userid); if (v?.Art == null || v.Thumb == null) { continue; } pp.Art = prov.ReplaceSchemeHost(v.Art); pp.Thumb = prov.ReplaceSchemeHost(v.Thumb); break; } } } if (pp.Art != null) { break; } } if (pp.Art == null) { foreach (SVR_GroupFilter gg in gfs .Where(a => (a.FilterType & (int)GroupFilterType.Directory) == (int)GroupFilterType.Directory && a.InvisibleInClients == 0) .Randomize(f.GroupFilterID)) { GetValidVideoRecursive(prov, gg, userid, pp); if (pp.Art != null) { break; } } } pp.LeafCount = gfs.Count; pp.ViewedLeafCount = 0; }
private void buttonSelectCategoryImages_Click(object sender, EventArgs e) { DialogResult randomize = MessageBox.Show("Randomize selection?", "Choose an option", MessageBoxButtons.YesNoCancel); if (randomize != DialogResult.Cancel) { HashSet <string> images = new HashSet <string>(); foreach (TagData tag in ActiveCategory.Tags) { foreach (string image in tag.GetLinkedImages()) { images.Add(image); } } string[] selectedImages = randomize == DialogResult.Yes ? images.Randomize().ToArray() : images.ToArray(); WallpaperData.WallpaperManagerForm.RebuildImageSelector(selectedImages, randomize != DialogResult.Yes); } }
public static Directory DirectoryFromFilter(IProvider prov, SVR_GroupFilter gg, int userid) { Directory pp = new Directory { Type = "show" }; pp.Key = prov.ConstructFilterIdUrl(userid, gg.GroupFilterID); pp.Title = gg.GroupFilterName; pp.Id = gg.GroupFilterID; pp.AnimeType = AnimeTypes.AnimeGroupFilter.ToString(); if ((gg.FilterType & (int)GroupFilterType.Directory) == (int)GroupFilterType.Directory) { GetValidVideoRecursive(prov, gg, userid, pp); } else if (gg.GroupsIds.ContainsKey(userid)) { HashSet <int> groups = gg.GroupsIds[userid]; if (groups.Count == 0) { return(pp); } pp.LeafCount = groups.Count; pp.ViewedLeafCount = 0; foreach (int grp in groups.Randomize()) { SVR_AnimeGroup ag = RepoFactory.AnimeGroup.GetByID(grp); Video v = ag.GetPlexContract(userid); if (v?.Art == null || v.Thumb == null) { continue; } pp.Art = prov.ReplaceSchemeHost(v.Art); pp.Thumb = prov.ReplaceSchemeHost(v.Thumb); break; } return(pp); } return(pp); }
private void ConnectionManagerThread(object state) { Thread.CurrentThread.Name = "ConnectionsManager_ConnectionManagerThread"; Thread.CurrentThread.Priority = ThreadPriority.Lowest; var connectionManager = state as ConnectionManager; if (connectionManager == null) return; try { var packetManager = _packetControlManager[connectionManager.Node]; var nodeUpdateTime = new Stopwatch(); var updateTime = new Stopwatch(); updateTime.Start(); var blockDiffusionTime = new Stopwatch(); blockDiffusionTime.Start(); var metadataUpdateTime = new Stopwatch(); metadataUpdateTime.Start(); for (;;) { Thread.Sleep(1000); if (this.State == ManagerState.Stop) return; if (!_connectionManagers.Contains(connectionManager)) return; var connectionCount = 0; lock (_thisLock) { connectionCount = _connectionManagers.Count; } // PushNodes if (!nodeUpdateTime.IsRunning || nodeUpdateTime.Elapsed.TotalMinutes >= 3) { nodeUpdateTime.Restart(); var nodes = new HashSet<Node>(); lock (_thisLock) { foreach (var node in _routeTable.Randomize()) { if (nodes.Count >= 64) break; if (node.Uris.Any(n => _succeededUris.Contains(n))) { nodes.Add(node); } } foreach (var node in _routeTable.Randomize()) { if (nodes.Count >= 128) break; nodes.Add(node); } } if (nodes.Count > 0) { connectionManager.PushNodes(nodes.Randomize()); Debug.WriteLine(string.Format("ConnectionManager: Push Nodes ({0})", nodes.Count)); _pushNodeCount.Add(nodes.Count); } } if (updateTime.Elapsed.TotalSeconds >= 60) { updateTime.Restart(); // PushBlocksLink if (connectionCount >= _uploadingConnectionCountLowerLimit) { List<Key> targetList = null; lock (_pushBlocksLinkDictionary.ThisLock) { if (_pushBlocksLinkDictionary.TryGetValue(connectionManager.Node, out targetList)) { _pushBlocksLinkDictionary.Remove(connectionManager.Node); } } if (targetList != null) { connectionManager.PushBlocksLink(targetList); Debug.WriteLine(string.Format("ConnectionManager: Push BlocksLink ({0})", targetList.Count)); _pushBlockLinkCount.Add(targetList.Count); } } // PushBlocksRequest if (connectionCount >= _downloadingConnectionCountLowerLimit) { List<Key> targetList = null; lock (_pushBlocksRequestDictionary.ThisLock) { if (_pushBlocksRequestDictionary.TryGetValue(connectionManager.Node, out targetList)) { _pushBlocksRequestDictionary.Remove(connectionManager.Node); } } if (targetList != null) { connectionManager.PushBlocksRequest(targetList); packetManager.PushBlocksRequest.AddRange(targetList); Debug.WriteLine(string.Format("ConnectionManager: Push BlocksRequest ({0})", targetList.Count)); _pushBlockRequestCount.Add(targetList.Count); } } // PushBroadcastMetadatasRequest if (connectionCount >= _downloadingConnectionCountLowerLimit) { List<string> targetList = null; lock (_pushBroadcastMetadatasRequestDictionary.ThisLock) { if (_pushBroadcastMetadatasRequestDictionary.TryGetValue(connectionManager.Node, out targetList)) { _pushBroadcastMetadatasRequestDictionary.Remove(connectionManager.Node); } } if (targetList != null) { connectionManager.PushBroadcastMetadatasRequest(targetList); foreach (var item in targetList) { _pushBroadcastMetadatasRequestList.Remove(item); } Debug.WriteLine(string.Format("ConnectionManager: Push BroadcastMetadatasRequest ({0})", targetList.Count)); _pushMetadataRequestCount.Add(targetList.Count); } } // PushUnicastMetadatasRequest if (connectionCount >= _downloadingConnectionCountLowerLimit) { List<string> targetList = null; lock (_pushUnicastMetadatasRequestDictionary.ThisLock) { if (_pushUnicastMetadatasRequestDictionary.TryGetValue(connectionManager.Node, out targetList)) { _pushUnicastMetadatasRequestDictionary.Remove(connectionManager.Node); } } if (targetList != null) { connectionManager.PushUnicastMetadatasRequest(targetList); foreach (var item in targetList) { _pushUnicastMetadatasRequestList.Remove(item); } Debug.WriteLine(string.Format("ConnectionManager: Push UnicastMetadatasRequest ({0})", targetList.Count)); _pushMetadataRequestCount.Add(targetList.Count); } } // PushMulticastMetadatasRequest if (connectionCount >= _downloadingConnectionCountLowerLimit) { List<Tag> targetList = null; lock (_pushMulticastMetadatasRequestDictionary.ThisLock) { if (_pushMulticastMetadatasRequestDictionary.TryGetValue(connectionManager.Node, out targetList)) { _pushMulticastMetadatasRequestDictionary.Remove(connectionManager.Node); } } if (targetList != null) { connectionManager.PushMulticastMetadatasRequest(targetList); foreach (var item in targetList) { _pushMulticastMetadatasRequestList.Remove(item); } Debug.WriteLine(string.Format("ConnectionManager: Push MulticastMetadatasRequest ({0})", targetList.Count)); _pushMetadataRequestCount.Add(targetList.Count); } } } if (blockDiffusionTime.Elapsed.TotalSeconds >= 3) { blockDiffusionTime.Restart(); // PushBlock if (connectionCount >= _uploadingConnectionCountLowerLimit) { Key key = null; lock (_diffusionBlocksDictionary.ThisLock) { Queue<Key> queue; if (_diffusionBlocksDictionary.TryGetValue(connectionManager.Node, out queue)) { if (queue.Count > 0) { key = queue.Dequeue(); } } } if (key != null) { var buffer = new ArraySegment<byte>(); try { buffer = _cacheManager[key]; connectionManager.PushBlock(key, buffer); Debug.WriteLine(string.Format("ConnectionManager: Push Block (Diffusion) ({0})", NetworkConverter.ToBase64UrlString(key.Hash))); _pushBlockCount.Increment(); packetManager.PullBlocksRequest.Remove(key); } catch (BlockNotFoundException) { } finally { if (buffer.Array != null) { _bufferManager.ReturnBuffer(buffer.Array); } } _blockUploadedEventQueue.Enqueue(key); _settings.UploadBlocksRequest.Remove(key); _settings.DiffusionBlocksRequest.Remove(key); } } } if (_random.NextDouble() < this.GetPriority(connectionManager.Node)) { // PushBlock if (connectionCount >= _uploadingConnectionCountLowerLimit) { Key key = null; lock (_uploadBlocksDictionary.ThisLock) { Queue<Key> queue; if (_uploadBlocksDictionary.TryGetValue(connectionManager.Node, out queue)) { if (queue.Count > 0) { key = queue.Dequeue(); } } } if (key != null) { var buffer = new ArraySegment<byte>(); try { buffer = _cacheManager[key]; connectionManager.PushBlock(key, buffer); Debug.WriteLine(string.Format("ConnectionManager: Push Block (Upload) ({0})", NetworkConverter.ToBase64UrlString(key.Hash))); _pushBlockCount.Increment(); packetManager.PullBlocksRequest.Remove(key); packetManager.Priority.Decrement(); // Infomation { if (_relayBlocks.Contains(key)) { _relayBlockCount.Increment(); } } } catch (BlockNotFoundException) { } finally { if (buffer.Array != null) { _bufferManager.ReturnBuffer(buffer.Array); } } _blockUploadedEventQueue.Enqueue(key); _settings.UploadBlocksRequest.Remove(key); _settings.DiffusionBlocksRequest.Remove(key); } } } if (metadataUpdateTime.Elapsed.TotalSeconds >= 60) { metadataUpdateTime.Restart(); // PushBroadcastMetadatas if (connectionCount >= _uploadingConnectionCountLowerLimit) { { var signatures = packetManager.PullBroadcastMetadatasRequest.ToArray(); var broadcastMetadats = new List<BroadcastMetadata>(); _random.Shuffle(signatures); foreach (var signature in signatures) { foreach (var metadata in _settings.MetadataManager.GetBroadcastMetadatas(signature).Randomize()) { if (!packetManager.StockBroadcastMetadatas.Contains(metadata.CreateHash(_hashAlgorithm))) { broadcastMetadats.Add(metadata); if (broadcastMetadats.Count >= _maxMetadataCount) goto End; } } } End:; if (broadcastMetadats.Count > 0) { connectionManager.PushBroadcastMetadatas(broadcastMetadats); Debug.WriteLine(string.Format("ConnectionManager: Push BroadcastMetadatas ({0})", broadcastMetadats.Count)); _pushMetadataCount.Add(broadcastMetadats.Count); foreach (var metadata in broadcastMetadats) { packetManager.StockBroadcastMetadatas.Add(metadata.CreateHash(_hashAlgorithm)); } } } } // PushUnicastMetadatas if (connectionCount >= _uploadingConnectionCountLowerLimit) { { var signatures = packetManager.PullUnicastMetadatasRequest.ToArray(); var unicastMetadata = new List<UnicastMetadata>(); _random.Shuffle(signatures); foreach (var signature in signatures) { foreach (var metadata in _settings.MetadataManager.GetUnicastMetadatas(signature).Randomize()) { if (!packetManager.StockUnicastMetadatas.Contains(metadata.CreateHash(_hashAlgorithm))) { unicastMetadata.Add(metadata); if (unicastMetadata.Count >= _maxMetadataCount) goto End; } } } End:; if (unicastMetadata.Count > 0) { connectionManager.PushUnicastMetadatas(unicastMetadata); Debug.WriteLine(string.Format("ConnectionManager: Push UnicastMetadatas ({0})", unicastMetadata.Count)); _pushMetadataCount.Add(unicastMetadata.Count); foreach (var metadata in unicastMetadata) { packetManager.StockUnicastMetadatas.Add(metadata.CreateHash(_hashAlgorithm)); } } } } // PushMulticastMetadatas if (connectionCount >= _uploadingConnectionCountLowerLimit) { { var tags = packetManager.PullMulticastMetadatasRequest.ToArray(); var multicastMetadatas = new List<MulticastMetadata>(); _random.Shuffle(tags); foreach (var tag in tags) { foreach (var metadata in _settings.MetadataManager.GetMulticastMetadatas(tag).Randomize()) { if (!packetManager.StockMulticastMetadatas.Contains(metadata.CreateHash(_hashAlgorithm))) { multicastMetadatas.Add(metadata); if (multicastMetadatas.Count >= _maxMetadataCount) goto End; } } } End:; if (multicastMetadatas.Count > 0) { connectionManager.PushMulticastMetadatas(multicastMetadatas); Debug.WriteLine(string.Format("ConnectionManager: Push MulticastMetadatas ({0})", multicastMetadatas.Count)); _pushMetadataCount.Add(multicastMetadatas.Count); foreach (var metadata in multicastMetadatas) { packetManager.StockMulticastMetadatas.Add(metadata.CreateHash(_hashAlgorithm)); } } } } } } } catch (Exception e) { Debug.WriteLine(e); } finally { this.RemoveConnectionManager(connectionManager); } }
private void CreateConnectionThread() { for (;;) { if (this.State == ManagerState.Stop) return; Thread.Sleep(1000); // 接続数を制限する。 { var connectionCount = 0; lock (_thisLock) { connectionCount = _connectionManagers.Count(n => n.Direction == ConnectDirection.Out); } if (connectionCount >= (this.ConnectionCountLimit / 2)) { continue; } } Node node = null; lock (_thisLock) { node = _routeTable .ToArray() .Where(n => !_connectionManagers.Any(m => CollectionUtils.Equals(m.Node.Id, n.Id)) && !_creatingNodes.Contains(n) && !_waitingNodes.Contains(n)) .Randomize() .FirstOrDefault(); if (node == null) continue; _creatingNodes.Add(node); _waitingNodes.Add(node); } try { var uris = new HashSet<string>(); uris.UnionWith(node.Uris.Take(12)); if (uris.Count == 0) { lock (_thisLock) { _removeNodes.Remove(node); _routeTable.Remove(node); } continue; } foreach (var uri in uris.Randomize()) { if (this.State == ManagerState.Stop) return; var connection = _clientManager.CreateConnection(uri, _bandwidthLimit); if (connection != null) { var connectionManager = new ConnectionManager(connection, _mySessionId, this.BaseNode, ConnectDirection.Out, _bufferManager); try { connectionManager.Connect(); if (!ConnectionsManager.Check(connectionManager.Node)) throw new ArgumentException(); _succeededUris.Add(uri); lock (_thisLock) { if (node != connectionManager.Node) { this.RemoveNode(connectionManager.Node); } if (connectionManager.Node.Uris.Count() != 0) { _routeTable.Live(connectionManager.Node); } } _connectConnectionCount.Increment(); this.AddConnectionManager(connectionManager, uri); goto End; } catch (Exception e) { Debug.WriteLine(e); connectionManager.Dispose(); } } } this.RemoveNode(node); End:; } finally { _creatingNodes.Remove(node); } } }
private void ConnectionsManagerThread() { var refreshStopwatch = new Stopwatch(); bool refreshThreadRunning = false; var pushBlockDiffusionStopwatch = new Stopwatch(); pushBlockDiffusionStopwatch.Start(); var pushBlockUploadStopwatch = new Stopwatch(); pushBlockUploadStopwatch.Start(); var pushBlockDownloadStopwatch = new Stopwatch(); pushBlockDownloadStopwatch.Start(); var pushMetadataUploadStopwatch = new Stopwatch(); pushMetadataUploadStopwatch.Start(); var pushMetadataDownloadStopwatch = new Stopwatch(); pushMetadataDownloadStopwatch.Start(); var requestCounts = new VolatileHashDictionary<Key, int>(new TimeSpan(0, 10, 0)); for (;;) { Thread.Sleep(1000); if (this.State == ManagerState.Stop) return; var connectionCount = 0; lock (_thisLock) { connectionCount = _connectionManagers.Count; } if (!refreshStopwatch.IsRunning || refreshStopwatch.Elapsed.TotalSeconds >= 60) { refreshStopwatch.Restart(); // トラストにより必要なMetadataを選択し、不要なMetadataを削除する。 Task.Run(() => { if (refreshThreadRunning) return; refreshThreadRunning = true; try { var lockSignatures = this.OnLockSignaturesEvent(); if (lockSignatures == null) return; var lockTags = this.OnLockTagsEvent(); if (lockTags == null) return; _settings.MetadataManager.Refresh(lockSignatures.ToArray(), lockTags.ToArray()); } catch (Exception e) { Log.Error(e); } finally { refreshThreadRunning = false; } }); } // 拡散アップロード if (connectionCount > _diffusionConnectionCountLowerLimit && pushBlockDiffusionStopwatch.Elapsed.TotalSeconds >= 60) { pushBlockDiffusionStopwatch.Restart(); // 拡散アップロードするブロック数を10000以下に抑える。 lock (_thisLock) { lock (_settings.DiffusionBlocksRequest.ThisLock) { if (_settings.DiffusionBlocksRequest.Count > 10000) { foreach (var key in _settings.DiffusionBlocksRequest.Randomize() .Take(_settings.DiffusionBlocksRequest.Count - 10000)) { _settings.DiffusionBlocksRequest.Remove(key); } } } } // 存在しないブロックのKeyをRemoveする。 lock (_thisLock) { lock (_settings.DiffusionBlocksRequest.ThisLock) { foreach (var key in _cacheManager.ExceptFrom(_settings.DiffusionBlocksRequest.ToArray()).ToArray()) { _settings.DiffusionBlocksRequest.Remove(key); } } lock (_settings.UploadBlocksRequest.ThisLock) { foreach (var key in _cacheManager.ExceptFrom(_settings.UploadBlocksRequest.ToArray()).ToArray()) { _settings.UploadBlocksRequest.Remove(key); } } } var baseNode = this.BaseNode; var otherNodes = new List<Node>(); lock (_thisLock) { otherNodes.AddRange(_connectionManagers.Select(n => n.Node)); } var packetManagers = new Dictionary<Node, PacketManager>(); foreach (var node in otherNodes) { packetManagers[node] = _packetControlManager[node]; } var diffusionBlocksList = new HashSet<Key>(); { { var array = _settings.UploadBlocksRequest.ToArray(); _random.Shuffle(array); int count = 1024; for (int i = 0; i < count && i < array.Length; i++) { diffusionBlocksList.Add(array[i]); } } { var array = _settings.DiffusionBlocksRequest.ToArray(); _random.Shuffle(array); int count = 1024; for (int i = 0; i < count && i < array.Length; i++) { diffusionBlocksList.Add(array[i]); } } } { var diffusionBlocksDictionary = new Dictionary<Node, List<Key>>(); foreach (var key in diffusionBlocksList.Randomize()) { try { var requestNodes = new List<Node>(); foreach (var node in Kademlia<Node>.Search(key.Hash, baseNode.Id, otherNodes, 2)) { requestNodes.Add(node); } if (requestNodes.Count == 0) { _blockUploadedEventQueue.Enqueue(key); _settings.UploadBlocksRequest.Remove(key); _settings.DiffusionBlocksRequest.Remove(key); continue; } for (int i = 0; i < requestNodes.Count; i++) { List<Key> collection; if (!diffusionBlocksDictionary.TryGetValue(requestNodes[i], out collection)) { collection = new List<Key>(); diffusionBlocksDictionary[requestNodes[i]] = collection; } collection.Add(key); } } catch (Exception e) { Log.Error(e); } } lock (_diffusionBlocksDictionary.ThisLock) { _diffusionBlocksDictionary.Clear(); foreach (var pair in diffusionBlocksDictionary) { var node = pair.Key; var targets = pair.Value; _random.Shuffle(targets); _diffusionBlocksDictionary.Add(node, new Queue<Key>(targets)); } } } } // アップロード if (connectionCount >= _uploadingConnectionCountLowerLimit && pushBlockUploadStopwatch.Elapsed.TotalSeconds >= 60) { pushBlockUploadStopwatch.Restart(); var baseNode = this.BaseNode; var otherNodes = new List<Node>(); lock (_thisLock) { otherNodes.AddRange(_connectionManagers.Select(n => n.Node)); } var packetManagers = new Dictionary<Node, PacketManager>(); foreach (var node in otherNodes) { packetManagers[node] = _packetControlManager[node]; } { var uploadBlocksDictionary = new Dictionary<Node, List<Key>>(); foreach (var pair in packetManagers) { var node = pair.Key; var packetManager = pair.Value; uploadBlocksDictionary.Add(node, _cacheManager.IntersectFrom(packetManager.PullBlocksRequest.ToArray().Randomize()).Take(1024).ToList()); } lock (_uploadBlocksDictionary.ThisLock) { _uploadBlocksDictionary.Clear(); foreach (var pair in uploadBlocksDictionary) { var node = pair.Key; var targets = pair.Value; _uploadBlocksDictionary.Add(node, new Queue<Key>(targets)); } } } } // ダウンロード if (connectionCount >= _downloadingConnectionCountLowerLimit && pushBlockDownloadStopwatch.Elapsed.TotalSeconds >= 60) { pushBlockDownloadStopwatch.Restart(); var baseNode = this.BaseNode; var otherNodes = new List<Node>(); lock (_thisLock) { otherNodes.AddRange(_connectionManagers.Select(n => n.Node)); } var packetManagers = new Dictionary<Node, PacketManager>(); foreach (var node in otherNodes) { packetManagers[node] = _packetControlManager[node]; } var pushBlocksLinkList = new HashSet<Key>(); var pushBlocksRequestList = new HashSet<Key>(); { { var array = _cacheManager.ToArray(); _random.Shuffle(array); int count = _maxBlockLinkCount; pushBlocksLinkList.UnionWith(array.Take(count)); } foreach (var pair in packetManagers) { var node = pair.Key; var packetManager = pair.Value; { var array = packetManager.PullBlocksLink.ToArray(new TimeSpan(0, 10, 0)); _random.Shuffle(array); var count = (int)((_maxBlockLinkCount * ((double)12 / otherNodes.Count)) * this.GetPriority(node)); pushBlocksLinkList.UnionWith(array.Take(count)); } } { var array = _cacheManager.ExceptFrom(_downloadBlocks.ToArray()).ToArray(); _random.Shuffle(array); int count = _maxBlockRequestCount; pushBlocksRequestList.UnionWith(array.Take(count)); } foreach (var pair in packetManagers) { var node = pair.Key; var packetManager = pair.Value; { var array = _cacheManager.ExceptFrom(packetManager.PullBlocksRequest.ToArray(new TimeSpan(0, 10, 0))).ToArray(); _random.Shuffle(array); var count = (int)((_maxBlockRequestCount * ((double)12 / otherNodes.Count)) * this.GetPriority(node)); pushBlocksRequestList.UnionWith(array.Take(count)); } } } { var pushBlocksLinkDictionary = new Dictionary<Node, List<Key>>(); foreach (var key in pushBlocksLinkList.Randomize()) { try { var requestNodes = new List<Node>(); foreach (var node in Kademlia<Node>.Search(key.Hash, otherNodes, 2)) { requestNodes.Add(node); } for (int i = 0; i < requestNodes.Count; i++) { List<Key> collection; if (!pushBlocksLinkDictionary.TryGetValue(requestNodes[i], out collection)) { collection = new List<Key>(); pushBlocksLinkDictionary[requestNodes[i]] = collection; } if (collection.Count < _maxBlockLinkCount) { collection.Add(key); } } } catch (Exception e) { Log.Error(e); } } lock (_pushBlocksLinkDictionary.ThisLock) { _pushBlocksLinkDictionary.Clear(); foreach (var pair in pushBlocksLinkDictionary) { var node = pair.Key; var targets = pair.Value; _random.Shuffle(targets); _pushBlocksLinkDictionary.Add(node, targets); } } } { requestCounts.Update(); var pushBlocksRequestDictionary = new Dictionary<Node, List<Key>>(); foreach (var key in pushBlocksRequestList.Randomize()) { int count; { int value; requestCounts.TryGetValue(key, out value); if (value < 6) requestCounts[key] = (value += 2); count = value; } try { var requestNodes = new List<Node>(); foreach (var node in Kademlia<Node>.Search(key.Hash, otherNodes, count)) { requestNodes.Add(node); } foreach (var pair in packetManagers) { var node = pair.Key; var packetManager = pair.Value; if (packetManager.PullBlocksLink.Contains(key)) { requestNodes.Add(node); } } for (int i = 0; i < requestNodes.Count; i++) { List<Key> collection; if (!pushBlocksRequestDictionary.TryGetValue(requestNodes[i], out collection)) { collection = new List<Key>(); pushBlocksRequestDictionary[requestNodes[i]] = collection; } if (collection.Count < _maxBlockRequestCount) { collection.Add(key); } } } catch (Exception e) { Log.Error(e); } } lock (_pushBlocksRequestDictionary.ThisLock) { _pushBlocksRequestDictionary.Clear(); foreach (var pair in pushBlocksRequestDictionary) { var node = pair.Key; var targets = pair.Value; _random.Shuffle(targets); _pushBlocksRequestDictionary.Add(node, targets); } } } } // Metadataのアップロード if (connectionCount >= _uploadingConnectionCountLowerLimit && pushMetadataUploadStopwatch.Elapsed.TotalMinutes >= 3) { pushMetadataUploadStopwatch.Restart(); var baseNode = this.BaseNode; var otherNodes = new List<Node>(); lock (_thisLock) { otherNodes.AddRange(_connectionManagers.Select(n => n.Node)); } var packetManagers = new Dictionary<Node, PacketManager>(); foreach (var node in otherNodes) { packetManagers[node] = _packetControlManager[node]; } // Broadcast foreach (var signature in _settings.MetadataManager.GetBroadcastSignatures()) { try { var requestNodes = new List<Node>(); foreach (var node in Kademlia<Node>.Search(Signature.GetHash(signature), otherNodes, 2)) { requestNodes.Add(node); } for (int i = 0; i < requestNodes.Count; i++) { packetManagers[requestNodes[i]].PullBroadcastMetadatasRequest.Add(signature); } } catch (Exception e) { Log.Error(e); } } // Unicast foreach (var signature in _settings.MetadataManager.GetUnicastSignatures()) { try { var requestNodes = new List<Node>(); foreach (var node in Kademlia<Node>.Search(Signature.GetHash(signature), otherNodes, 2)) { requestNodes.Add(node); } for (int i = 0; i < requestNodes.Count; i++) { packetManagers[requestNodes[i]].PullUnicastMetadatasRequest.Add(signature); } } catch (Exception e) { Log.Error(e); } } // Multicast { foreach (var tag in _settings.MetadataManager.GetMulticastTags()) { try { var requestNodes = new List<Node>(); foreach (var node in Kademlia<Node>.Search(tag.Id, otherNodes, 2)) { requestNodes.Add(node); } for (int i = 0; i < requestNodes.Count; i++) { packetManagers[requestNodes[i]].PullMulticastMetadatasRequest.Add(tag); } } catch (Exception e) { Log.Error(e); } } } } // Metadataのダウンロード if (connectionCount >= _downloadingConnectionCountLowerLimit && pushMetadataDownloadStopwatch.Elapsed.TotalSeconds >= 60) { pushMetadataDownloadStopwatch.Restart(); var baseNode = this.BaseNode; var otherNodes = new List<Node>(); lock (_thisLock) { otherNodes.AddRange(_connectionManagers.Select(n => n.Node)); } var packetManagers = new Dictionary<Node, PacketManager>(); foreach (var node in otherNodes) { packetManagers[node] = _packetControlManager[node]; } var pushBroadcastMetadatasRequestList = new HashSet<string>(); var pushUnicastMetadatasRequestList = new HashSet<string>(); var pushMulticastMetadatasRequestList = new HashSet<Tag>(); { // Broadcast { { var array = _pushBroadcastMetadatasRequestList.ToArray(); _random.Shuffle(array); int count = _maxMetadataRequestCount; for (int i = 0; count > 0 && i < array.Length; i++) { pushBroadcastMetadatasRequestList.Add(array[i]); count--; } } foreach (var pair in packetManagers) { var node = pair.Key; var packetManager = pair.Value; { var array = packetManager.PullBroadcastMetadatasRequest.ToArray(new TimeSpan(0, 10, 0)); _random.Shuffle(array); int count = _maxMetadataRequestCount; for (int i = 0; count > 0 && i < array.Length; i++) { pushBroadcastMetadatasRequestList.Add(array[i]); count--; } } } } // Unicast { { var array = _pushUnicastMetadatasRequestList.ToArray(); _random.Shuffle(array); int count = _maxMetadataRequestCount; for (int i = 0; count > 0 && i < array.Length; i++) { pushUnicastMetadatasRequestList.Add(array[i]); count--; } } foreach (var pair in packetManagers) { var node = pair.Key; var packetManager = pair.Value; { var array = packetManager.PullUnicastMetadatasRequest.ToArray(new TimeSpan(0, 10, 0)); _random.Shuffle(array); int count = _maxMetadataRequestCount; for (int i = 0; count > 0 && i < array.Length; i++) { pushUnicastMetadatasRequestList.Add(array[i]); count--; } } } } // Multicast { { var array = _pushMulticastMetadatasRequestList.ToArray(); _random.Shuffle(array); int count = _maxMetadataRequestCount; for (int i = 0; count > 0 && i < array.Length; i++) { pushMulticastMetadatasRequestList.Add(array[i]); count--; } } foreach (var pair in packetManagers) { var node = pair.Key; var packetManager = pair.Value; { var array = packetManager.PullMulticastMetadatasRequest.ToArray(new TimeSpan(0, 10, 0)); _random.Shuffle(array); int count = _maxMetadataRequestCount; for (int i = 0; count > 0 && i < array.Length; i++) { pushMulticastMetadatasRequestList.Add(array[i]); count--; } } } } } { // Broadcast { var pushBroadcastMetadatasRequestDictionary = new Dictionary<Node, List<string>>(); foreach (var signature in pushBroadcastMetadatasRequestList.Randomize()) { try { var requestNodes = new List<Node>(); foreach (var node in Kademlia<Node>.Search(Signature.GetHash(signature), otherNodes, 2)) { requestNodes.Add(node); } for (int i = 0; i < requestNodes.Count; i++) { List<string> collection; if (!pushBroadcastMetadatasRequestDictionary.TryGetValue(requestNodes[i], out collection)) { collection = new List<string>(); pushBroadcastMetadatasRequestDictionary[requestNodes[i]] = collection; } if (collection.Count < _maxMetadataRequestCount) { collection.Add(signature); } } } catch (Exception e) { Log.Error(e); } } lock (_pushBroadcastMetadatasRequestDictionary.ThisLock) { _pushBroadcastMetadatasRequestDictionary.Clear(); foreach (var pair in pushBroadcastMetadatasRequestDictionary) { var node = pair.Key; var targets = pair.Value; _random.Shuffle(targets); _pushBroadcastMetadatasRequestDictionary.Add(node, targets); } } } // Unicast { var pushUnicastMetadatasRequestDictionary = new Dictionary<Node, List<string>>(); foreach (var signature in pushUnicastMetadatasRequestList.Randomize()) { try { var requestNodes = new List<Node>(); foreach (var node in Kademlia<Node>.Search(Signature.GetHash(signature), otherNodes, 2)) { requestNodes.Add(node); } for (int i = 0; i < requestNodes.Count; i++) { List<string> collection; if (!pushUnicastMetadatasRequestDictionary.TryGetValue(requestNodes[i], out collection)) { collection = new List<string>(); pushUnicastMetadatasRequestDictionary[requestNodes[i]] = collection; } if (collection.Count < _maxMetadataRequestCount) { collection.Add(signature); } } } catch (Exception e) { Log.Error(e); } } lock (_pushUnicastMetadatasRequestDictionary.ThisLock) { _pushUnicastMetadatasRequestDictionary.Clear(); foreach (var pair in pushUnicastMetadatasRequestDictionary) { var node = pair.Key; var targets = pair.Value; _random.Shuffle(targets); _pushUnicastMetadatasRequestDictionary.Add(node, targets); } } } // Multicast { var pushMulticastMetadatasRequestDictionary = new Dictionary<Node, List<Tag>>(); foreach (var tag in pushMulticastMetadatasRequestList.Randomize()) { try { var requestNodes = new List<Node>(); foreach (var node in Kademlia<Node>.Search(tag.Id, otherNodes, 2)) { requestNodes.Add(node); } for (int i = 0; i < requestNodes.Count; i++) { List<Tag> collection; if (!pushMulticastMetadatasRequestDictionary.TryGetValue(requestNodes[i], out collection)) { collection = new List<Tag>(); pushMulticastMetadatasRequestDictionary[requestNodes[i]] = collection; } if (collection.Count < _maxMetadataRequestCount) { collection.Add(tag); } } } catch (Exception e) { Log.Error(e); } } lock (_pushMulticastMetadatasRequestDictionary.ThisLock) { _pushMulticastMetadatasRequestDictionary.Clear(); foreach (var pair in pushMulticastMetadatasRequestDictionary) { var node = pair.Key; var targets = pair.Value; _random.Shuffle(targets); _pushMulticastMetadatasRequestDictionary.Add(node, targets); } } } } } } }
private void ConnectionManagerThread(object state) { Thread.CurrentThread.Name = "ConnectionsManager_ConnectionManagerThread"; Thread.CurrentThread.Priority = ThreadPriority.Lowest; var connectionManager = state as ConnectionManager; if (connectionManager == null) return; try { var messageManager = _messagesManager[connectionManager.Node]; Stopwatch nodeUpdateTime = new Stopwatch(); Stopwatch updateTime = new Stopwatch(); updateTime.Start(); Stopwatch blockDiffusionTime = new Stopwatch(); blockDiffusionTime.Start(); Stopwatch metadataUpdateTime = new Stopwatch(); metadataUpdateTime.Start(); for (; ; ) { Thread.Sleep(1000); if (this.State == ManagerState.Stop) return; if (!_connectionManagers.Contains(connectionManager)) return; var connectionCount = 0; lock (this.ThisLock) { connectionCount = _connectionManagers.Count; } // PushNodes if (!nodeUpdateTime.IsRunning || nodeUpdateTime.Elapsed.TotalMinutes >= 3) { nodeUpdateTime.Restart(); var nodes = new HashSet<Node>(); lock (this.ThisLock) { foreach (var node in _routeTable.Randomize()) { if (nodes.Count >= 64) break; if (node.Uris.Any(n => _succeededUris.Contains(n))) { nodes.Add(node); } } foreach (var node in _routeTable.Randomize()) { if (nodes.Count >= 128) break; nodes.Add(node); } } if (nodes.Count > 0) { connectionManager.PushNodes(nodes.Randomize()); Debug.WriteLine(string.Format("ConnectionManager: Push Nodes ({0})", nodes.Count)); _pushNodeCount.Add(nodes.Count); } } if (updateTime.Elapsed.TotalSeconds >= 60) { updateTime.Restart(); // PushBlocksLink if (connectionCount >= _uploadingConnectionCountLowerLimit) { List<Key> targetList = null; lock (_pushBlocksLinkDictionary.ThisLock) { if (_pushBlocksLinkDictionary.TryGetValue(connectionManager.Node, out targetList)) { _pushBlocksLinkDictionary.Remove(connectionManager.Node); messageManager.PushBlocksLink.AddRange(targetList); } } if (targetList != null) { try { connectionManager.PushBlocksLink(targetList); Debug.WriteLine(string.Format("ConnectionManager: Push BlocksLink ({0})", targetList.Count)); _pushBlockLinkCount.Add(targetList.Count); } catch (Exception e) { foreach (var item in targetList) { messageManager.PushBlocksLink.Remove(item); } throw e; } } } // PushBlocksRequest if (connectionCount >= _downloadingConnectionCountLowerLimit) { List<Key> targetList = null; lock (_pushBlocksRequestDictionary.ThisLock) { if (_pushBlocksRequestDictionary.TryGetValue(connectionManager.Node, out targetList)) { _pushBlocksRequestDictionary.Remove(connectionManager.Node); messageManager.PushBlocksRequest.AddRange(targetList); } } if (targetList != null) { try { connectionManager.PushBlocksRequest(targetList); Debug.WriteLine(string.Format("ConnectionManager: Push BlocksRequest ({0})", targetList.Count)); _pushBlockRequestCount.Add(targetList.Count); } catch (Exception e) { foreach (var item in targetList) { messageManager.PushBlocksRequest.Remove(item); } throw e; } } } // PushBroadcastMetadatasRequest if (connectionCount >= _downloadingConnectionCountLowerLimit) { List<string> targetList = null; lock (_pushBroadcastSignaturesRequestDictionary.ThisLock) { if (_pushBroadcastSignaturesRequestDictionary.TryGetValue(connectionManager.Node, out targetList)) { _pushBroadcastSignaturesRequestDictionary.Remove(connectionManager.Node); messageManager.PushBroadcastSignaturesRequest.AddRange(targetList); } } if (targetList != null) { try { connectionManager.PushBroadcastMetadatasRequest(targetList); foreach (var item in targetList) { _pushBroadcastSignaturesRequestList.Remove(item); } Debug.WriteLine(string.Format("ConnectionManager: Push BroadcastMetadatasRequest ({0})", targetList.Count)); _pushMetadataRequestCount.Add(targetList.Count); } catch (Exception e) { foreach (var item in targetList) { messageManager.PushBroadcastSignaturesRequest.Remove(item); } throw e; } } } // PushUnicastMetadatasRequest if (connectionCount >= _downloadingConnectionCountLowerLimit) { List<string> targetList = null; lock (_pushUnicastSignaturesRequestDictionary.ThisLock) { if (_pushUnicastSignaturesRequestDictionary.TryGetValue(connectionManager.Node, out targetList)) { _pushUnicastSignaturesRequestDictionary.Remove(connectionManager.Node); messageManager.PushUnicastSignaturesRequest.AddRange(targetList); } } if (targetList != null) { try { connectionManager.PushUnicastMetadatasRequest(targetList); foreach (var item in targetList) { _pushUnicastSignaturesRequestList.Remove(item); } Debug.WriteLine(string.Format("ConnectionManager: Push UnicastMetadatasRequest ({0})", targetList.Count)); _pushMetadataRequestCount.Add(targetList.Count); } catch (Exception e) { foreach (var item in targetList) { messageManager.PushUnicastSignaturesRequest.Remove(item); } throw e; } } } // PushMulticastMetadatasRequest if (connectionCount >= _downloadingConnectionCountLowerLimit) { { List<Wiki> wikiList = null; List<Chat> chatList = null; lock (_pushMulticastWikisRequestDictionary.ThisLock) { if (_pushMulticastWikisRequestDictionary.TryGetValue(connectionManager.Node, out wikiList)) { _pushMulticastWikisRequestDictionary.Remove(connectionManager.Node); messageManager.PushMulticastWikisRequest.AddRange(wikiList); } } lock (_pushMulticastChatsRequestDictionary.ThisLock) { if (_pushMulticastChatsRequestDictionary.TryGetValue(connectionManager.Node, out chatList)) { _pushMulticastChatsRequestDictionary.Remove(connectionManager.Node); messageManager.PushMulticastChatsRequest.AddRange(chatList); } } if (wikiList != null || chatList != null) { try { connectionManager.PushMulticastMetadatasRequest(wikiList, chatList); int tagCount = 0; if (wikiList != null) { foreach (var item in wikiList) { _pushMulticastWikisRequestList.Remove(item); } tagCount += wikiList.Count; } if (chatList != null) { foreach (var item in chatList) { _pushMulticastChatsRequestList.Remove(item); } tagCount += chatList.Count; } Debug.WriteLine(string.Format("ConnectionManager: Push MulticastMetadatasRequest ({0})", tagCount)); _pushMetadataRequestCount.Add(tagCount); } catch (Exception e) { if (wikiList != null) { foreach (var item in wikiList) { messageManager.PushMulticastWikisRequest.Remove(item); } } if (chatList != null) { foreach (var item in chatList) { messageManager.PushMulticastChatsRequest.Remove(item); } } throw e; } } } } } if (blockDiffusionTime.Elapsed.TotalSeconds >= 5) { blockDiffusionTime.Restart(); // PushBlock if (connectionCount >= _uploadingConnectionCountLowerLimit) { Key key = null; lock (_diffusionBlocksDictionary.ThisLock) { Queue<Key> queue; if (_diffusionBlocksDictionary.TryGetValue(connectionManager.Node, out queue)) { if (queue.Count > 0) { key = queue.Dequeue(); messageManager.StockBlocks.Add(key); } } } if (key != null) { ArraySegment<byte> buffer = new ArraySegment<byte>(); try { buffer = _cacheManager[key]; connectionManager.PushBlock(key, buffer); Debug.WriteLine(string.Format("ConnectionManager: Push Block (Diffusion) ({0})", NetworkConverter.ToBase64UrlString(key.Hash))); _pushBlockCount.Increment(); messageManager.PullBlocksRequest.Remove(key); } catch (ConnectionManagerException e) { messageManager.StockBlocks.Remove(key); throw e; } catch (BlockNotFoundException) { messageManager.StockBlocks.Remove(key); } finally { if (buffer.Array != null) { _bufferManager.ReturnBuffer(buffer.Array); } } _settings.UploadBlocksRequest.Remove(key); _settings.DiffusionBlocksRequest.Remove(key); } } } if (_random.NextDouble() < this.GetPriority(connectionManager.Node)) { // PushBlock if (connectionCount >= _uploadingConnectionCountLowerLimit) { Key key = null; lock (_uploadBlocksDictionary.ThisLock) { Queue<Key> queue; if (_uploadBlocksDictionary.TryGetValue(connectionManager.Node, out queue)) { if (queue.Count > 0) { key = queue.Dequeue(); messageManager.StockBlocks.Add(key); } } } if (key != null) { ArraySegment<byte> buffer = new ArraySegment<byte>(); try { buffer = _cacheManager[key]; connectionManager.PushBlock(key, buffer); Debug.WriteLine(string.Format("ConnectionManager: Push Block (Upload) ({0})", NetworkConverter.ToBase64UrlString(key.Hash))); _pushBlockCount.Increment(); messageManager.PullBlocksRequest.Remove(key); messageManager.Priority.Decrement(); // Infomation { if (_relayBlocks.Contains(key)) { _relayBlockCount.Increment(); } } } catch (ConnectionManagerException e) { messageManager.StockBlocks.Remove(key); throw e; } catch (BlockNotFoundException) { messageManager.StockBlocks.Remove(key); } finally { if (buffer.Array != null) { _bufferManager.ReturnBuffer(buffer.Array); } } _settings.UploadBlocksRequest.Remove(key); _settings.DiffusionBlocksRequest.Remove(key); } } } if (metadataUpdateTime.Elapsed.TotalSeconds >= 60) { metadataUpdateTime.Restart(); // PushBroadcastMetadatas if (connectionCount >= _uploadingConnectionCountLowerLimit) { { var signatures = messageManager.PullBroadcastSignaturesRequest.ToArray(); var profileMetadatas = new List<ProfileMetadata>(); _random.Shuffle(signatures); foreach (var signature in signatures) { var metadata = _settings.MetadataManager.GetProfileMetadata(signature); if (metadata == null) continue; if (!messageManager.StockProfileMetadatas.Contains(metadata.CreateHash(_hashAlgorithm))) { profileMetadatas.Add(metadata); if (profileMetadatas.Count >= _maxMetadataCount) break; } if (profileMetadatas.Count >= _maxMetadataCount) break; } if (profileMetadatas.Count > 0) { connectionManager.PushBroadcastMetadatas( profileMetadatas); var metadataCount = profileMetadatas.Count; Debug.WriteLine(string.Format("ConnectionManager: Push BroadcastMetadatas ({0})", metadataCount)); _pushMetadataCount.Add(metadataCount); foreach (var metadata in profileMetadatas) { messageManager.StockProfileMetadatas.Add(metadata.CreateHash(_hashAlgorithm)); } } } } // PushUnicastMetadatas if (connectionCount >= _uploadingConnectionCountLowerLimit) { { var signatures = messageManager.PullUnicastSignaturesRequest.ToArray(); var signatureMessageMetadatas = new List<SignatureMessageMetadata>(); _random.Shuffle(signatures); foreach (var signature in signatures) { foreach (var metadata in _settings.MetadataManager.GetSignatureMessageMetadatas(signature)) { if (!messageManager.StockSignatureMessageMetadatas.Contains(metadata.CreateHash(_hashAlgorithm))) { signatureMessageMetadatas.Add(metadata); if (signatureMessageMetadatas.Count >= _maxMetadataCount) break; } } if (signatureMessageMetadatas.Count >= _maxMetadataCount) break; } if (signatureMessageMetadatas.Count > 0) { connectionManager.PushUnicastMetadatas( signatureMessageMetadatas); var metadataCount = signatureMessageMetadatas.Count; Debug.WriteLine(string.Format("ConnectionManager: Push UnicastMetadatas ({0})", metadataCount)); _pushMetadataCount.Add(metadataCount); foreach (var metadata in signatureMessageMetadatas) { messageManager.StockSignatureMessageMetadatas.Add(metadata.CreateHash(_hashAlgorithm)); } } } } // PushMulticastMetadatas if (connectionCount >= _uploadingConnectionCountLowerLimit) { { var wikis = messageManager.PullMulticastWikisRequest.ToArray(); var chats = messageManager.PullMulticastChatsRequest.ToArray(); var wikiDocumentMetadatas = new List<WikiDocumentMetadata>(); var chatMessageMetadatas = new List<ChatMessageMetadata>(); _random.Shuffle(wikis); foreach (var tag in wikis) { foreach (var metadata in _settings.MetadataManager.GetWikiDocumentMetadatas(tag)) { if (!messageManager.StockWikiDocumentMetadatas.Contains(metadata.CreateHash(_hashAlgorithm))) { wikiDocumentMetadatas.Add(metadata); if (wikiDocumentMetadatas.Count >= _maxMetadataCount) break; } } if (wikiDocumentMetadatas.Count >= _maxMetadataCount) break; } _random.Shuffle(chats); foreach (var tag in chats) { foreach (var metadata in _settings.MetadataManager.GetChatMessageMetadatas(tag)) { if (!messageManager.StockChatMessageMetadatas.Contains(metadata.CreateHash(_hashAlgorithm))) { chatMessageMetadatas.Add(metadata); if (chatMessageMetadatas.Count >= _maxMetadataCount) break; } } if (chatMessageMetadatas.Count >= _maxMetadataCount) break; } if (wikiDocumentMetadatas.Count > 0 || chatMessageMetadatas.Count > 0) { connectionManager.PushMulticastMetadatas( wikiDocumentMetadatas, chatMessageMetadatas); var metadataCount = wikiDocumentMetadatas.Count + chatMessageMetadatas.Count; Debug.WriteLine(string.Format("ConnectionManager: Push MulticastMetadatas ({0})", metadataCount)); _pushMetadataCount.Add(metadataCount); foreach (var metadata in wikiDocumentMetadatas) { messageManager.StockWikiDocumentMetadatas.Add(metadata.CreateHash(_hashAlgorithm)); } foreach (var metadata in chatMessageMetadatas) { messageManager.StockChatMessageMetadatas.Add(metadata.CreateHash(_hashAlgorithm)); } } } } } } } catch (Exception e) { Debug.WriteLine(e); } finally { this.RemoveConnectionManager(connectionManager); } }
private void ConnectionManagerThread(object state) { Thread.CurrentThread.Name = "ConnectionsManager_ConnectionManagerThread"; Thread.CurrentThread.Priority = ThreadPriority.Lowest; var connectionManager = state as ConnectionManager; if (connectionManager == null) return; try { var messageManager = _messagesManager[connectionManager.Node]; Stopwatch checkTime = new Stopwatch(); checkTime.Start(); Stopwatch nodeUpdateTime = new Stopwatch(); Stopwatch updateTime = new Stopwatch(); updateTime.Start(); Stopwatch blockDiffusionTime = new Stopwatch(); blockDiffusionTime.Start(); Stopwatch seedUpdateTime = new Stopwatch(); seedUpdateTime.Start(); for (; ; ) { Thread.Sleep(1000); if (this.State == ManagerState.Stop) return; if (!_connectionManagers.Contains(connectionManager)) return; var connectionCount = 0; lock (this.ThisLock) { connectionCount = _connectionManagers.Count; } // Check if (messageManager.Priority < 0 && checkTime.Elapsed.TotalSeconds >= 5) { checkTime.Restart(); if ((DateTime.UtcNow - messageManager.LastPullTime).TotalMinutes >= 5) { lock (this.ThisLock) { this.RemoveNode(connectionManager.Node); } connectionManager.PushCancel(); Debug.WriteLine("ConnectionManager: Push Cancel"); return; } } // PushNodes if (!nodeUpdateTime.IsRunning || nodeUpdateTime.Elapsed.TotalMinutes >= 3) { nodeUpdateTime.Restart(); var nodes = new HashSet<Node>(); lock (this.ThisLock) { foreach (var node in _routeTable.Randomize()) { if (nodes.Count >= 64) break; if (node.Uris.Any(n => _succeededUris.Contains(n))) { nodes.Add(node); } } foreach (var node in _routeTable.Randomize()) { if (nodes.Count >= 128) break; nodes.Add(node); } } if (nodes.Count > 0) { connectionManager.PushNodes(nodes.Randomize()); Debug.WriteLine(string.Format("ConnectionManager: Push Nodes ({0})", nodes.Count)); _pushNodeCount.Add(nodes.Count); } } if (updateTime.Elapsed.TotalSeconds >= 30) { updateTime.Restart(); // PushBlocksLink if (connectionCount >= _uploadingConnectionCountLowerLimit) { List<Key> targetList = null; lock (_pushBlocksLinkDictionary.ThisLock) { if (_pushBlocksLinkDictionary.TryGetValue(connectionManager.Node, out targetList)) { _pushBlocksLinkDictionary.Remove(connectionManager.Node); messageManager.PushBlocksLink.AddRange(targetList); } } if (targetList != null) { try { connectionManager.PushBlocksLink(targetList); Debug.WriteLine(string.Format("ConnectionManager: Push BlocksLink ({0})", targetList.Count)); _pushBlockLinkCount.Add(targetList.Count); } catch (Exception e) { foreach (var item in targetList) { messageManager.PushBlocksLink.Remove(item); } throw e; } } } // PushBlocksRequest if (connectionCount >= _downloadingConnectionCountLowerLimit) { List<Key> targetList = null; lock (_pushBlocksRequestDictionary.ThisLock) { if (_pushBlocksRequestDictionary.TryGetValue(connectionManager.Node, out targetList)) { _pushBlocksRequestDictionary.Remove(connectionManager.Node); messageManager.PushBlocksRequest.AddRange(targetList); } } if (targetList != null) { try { connectionManager.PushBlocksRequest(targetList); Debug.WriteLine(string.Format("ConnectionManager: Push BlocksRequest ({0})", targetList.Count)); _pushBlockRequestCount.Add(targetList.Count); } catch (Exception e) { foreach (var item in targetList) { messageManager.PushBlocksRequest.Remove(item); } throw e; } } } // PushSeedsRequest if (connectionCount >= _downloadingConnectionCountLowerLimit) { List<string> targetList = null; lock (_pushSeedsRequestDictionary.ThisLock) { if (_pushSeedsRequestDictionary.TryGetValue(connectionManager.Node, out targetList)) { _pushSeedsRequestDictionary.Remove(connectionManager.Node); messageManager.PushSeedsRequest.AddRange(targetList); } } if (targetList != null) { try { connectionManager.PushSeedsRequest(targetList); foreach (var item in targetList) { _pushSeedsRequestList.Remove(item); } Debug.WriteLine(string.Format("ConnectionManager: Push SeedsRequest ({0})", targetList.Count)); _pushSeedRequestCount.Add(targetList.Count); } catch (Exception e) { foreach (var item in targetList) { messageManager.PushSeedsRequest.Remove(item); } throw e; } } } } if (blockDiffusionTime.Elapsed.TotalSeconds >= connectionCount) { blockDiffusionTime.Restart(); // PushBlock if (connectionCount >= _uploadingConnectionCountLowerLimit) { Key key = null; lock (_diffusionBlocksDictionary.ThisLock) { Queue<Key> queue; if (_diffusionBlocksDictionary.TryGetValue(connectionManager.Node, out queue)) { if (queue.Count > 0) { key = queue.Dequeue(); messageManager.StockBlocks.Add(key); } } } if (key != null) { ArraySegment<byte> buffer = new ArraySegment<byte>(); try { buffer = _cacheManager[key]; connectionManager.PushBlock(key, buffer); Debug.WriteLine(string.Format("ConnectionManager: Push Block (Diffusion) ({0})", NetworkConverter.ToBase64UrlString(key.Hash))); _pushBlockCount.Increment(); messageManager.PullBlocksRequest.Remove(key); } catch (ConnectionManagerException e) { messageManager.StockBlocks.Remove(key); throw e; } catch (BlockNotFoundException) { messageManager.StockBlocks.Remove(key); } finally { if (buffer.Array != null) { _bufferManager.ReturnBuffer(buffer.Array); } } _settings.UploadBlocksRequest.Remove(key); _settings.DiffusionBlocksRequest.Remove(key); this.OnUploadedEvent(new Key[] { key }); } } } if (_random.NextDouble() < this.GetPriority(connectionManager.Node)) { // PushBlock if (connectionCount >= _uploadingConnectionCountLowerLimit) { Key key = null; lock (_uploadBlocksDictionary.ThisLock) { Queue<Key> queue; if (_uploadBlocksDictionary.TryGetValue(connectionManager.Node, out queue)) { if (queue.Count > 0) { key = queue.Dequeue(); messageManager.StockBlocks.Add(key); } } } if (key != null) { ArraySegment<byte> buffer = new ArraySegment<byte>(); try { buffer = _cacheManager[key]; connectionManager.PushBlock(key, buffer); Debug.WriteLine(string.Format("ConnectionManager: Push Block (Upload) ({0})", NetworkConverter.ToBase64UrlString(key.Hash))); _pushBlockCount.Increment(); messageManager.PullBlocksRequest.Remove(key); messageManager.Priority.Decrement(); // Infomation { if (_relayBlocks.Contains(key)) { _relayBlockCount.Increment(); } } } catch (ConnectionManagerException e) { messageManager.StockBlocks.Remove(key); throw e; } catch (BlockNotFoundException) { messageManager.StockBlocks.Remove(key); } finally { if (buffer.Array != null) { _bufferManager.ReturnBuffer(buffer.Array); } } _settings.UploadBlocksRequest.Remove(key); _settings.DiffusionBlocksRequest.Remove(key); this.OnUploadedEvent(new Key[] { key }); } } } if (seedUpdateTime.Elapsed.TotalSeconds >= 30) { seedUpdateTime.Restart(); // PushSeeds if (connectionCount >= _uploadingConnectionCountLowerLimit) { var signatures = messageManager.PullSeedsRequest.ToArray(); var linkSeeds = new List<Seed>(); // Link _random.Shuffle(signatures); foreach (var signature in signatures) { Seed tempSeed = _settings.GetLinkSeed(signature); if (tempSeed == null) continue; DateTime creationTime; if (!messageManager.StockLinkSeeds.TryGetValue(signature, out creationTime) || tempSeed.CreationTime > creationTime) { linkSeeds.Add(tempSeed); if (linkSeeds.Count >= (_maxSeedCount / 2)) break; } } var storeSeeds = new List<Seed>(); // Store _random.Shuffle(signatures); foreach (var signature in signatures) { Seed tempSeed = _settings.GetStoreSeed(signature); if (tempSeed == null) continue; DateTime creationTime; if (!messageManager.StockStoreSeeds.TryGetValue(signature, out creationTime) || tempSeed.CreationTime > creationTime) { storeSeeds.Add(tempSeed); if (storeSeeds.Count >= (_maxSeedCount / 2)) break; } } if (linkSeeds.Count > 0 || storeSeeds.Count > 0) { var seeds = new List<Seed>(); seeds.AddRange(linkSeeds); seeds.AddRange(storeSeeds); _random.Shuffle(seeds); connectionManager.PushSeeds(seeds); Debug.WriteLine(string.Format("ConnectionManager: Push Seeds ({0})", seeds.Count)); _pushSeedCount.Add(seeds.Count); foreach (var seed in linkSeeds) { var signature = seed.Certificate.ToString(); messageManager.StockLinkSeeds[signature] = seed.CreationTime; } foreach (var seed in storeSeeds) { var signature = seed.Certificate.ToString(); messageManager.StockStoreSeeds[signature] = seed.CreationTime; } } } } } } catch (Exception e) { Debug.WriteLine(e); } finally { this.RemoveConnectionManager(connectionManager); } }