CoinKernelSet.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. namespace NTMiner.Core.Kernels.Impl {
  5. internal class CoinKernelSet : ICoinKernelSet {
  6. private readonly Dictionary<Guid, CoinKernelData> _dicById = new Dictionary<Guid, CoinKernelData>();
  7. public CoinKernelSet(IServerContext context) {
  8. context.AddCmdPath<AddCoinKernelCommand>("添加币种内核", LogEnum.DevConsole,
  9. action: (message) => {
  10. InitOnece();
  11. if (message == null || message.Input == null || message.Input.GetId() == Guid.Empty) {
  12. throw new ArgumentNullException();
  13. }
  14. if (!context.CoinSet.Contains(message.Input.CoinId)) {
  15. throw new ValidationException("there is no coin with id" + message.Input.CoinId);
  16. }
  17. if (_dicById.ContainsKey(message.Input.GetId())) {
  18. return;
  19. }
  20. if (_dicById.Values.Any(a => a.CoinId == message.Input.CoinId && a.KernelId == message.Input.KernelId)) {
  21. return;
  22. }
  23. CoinKernelData entity = new CoinKernelData().Update(message.Input);
  24. _dicById.Add(entity.Id, entity);
  25. var repository = NTMinerRoot.CreateServerRepository<CoinKernelData>();
  26. repository.Add(entity);
  27. VirtualRoot.RaiseEvent(new CoinKernelAddedEvent(message.Id, entity));
  28. if (context.CoinSet.TryGetCoin(message.Input.CoinId, out ICoin coin)) {
  29. IPool[] pools = context.PoolSet.AsEnumerable().Where(a => a.CoinId == coin.GetId()).ToArray();
  30. foreach (IPool pool in pools) {
  31. Guid poolKernelId = Guid.NewGuid();
  32. var poolKernel = new PoolKernelData() {
  33. Id = poolKernelId,
  34. Args = string.Empty,
  35. KernelId = message.Input.KernelId,
  36. PoolId = pool.GetId()
  37. };
  38. VirtualRoot.Execute(new AddPoolKernelCommand(poolKernel));
  39. }
  40. }
  41. });
  42. context.AddCmdPath<UpdateCoinKernelCommand>("更新币种内核", LogEnum.DevConsole,
  43. action: (message) => {
  44. InitOnece();
  45. if (message == null || message.Input == null || message.Input.GetId() == Guid.Empty) {
  46. throw new ArgumentNullException();
  47. }
  48. if (!context.CoinSet.Contains(message.Input.CoinId)) {
  49. throw new ValidationException("there is no coin with id" + message.Input.CoinId);
  50. }
  51. if (!_dicById.ContainsKey(message.Input.GetId())) {
  52. return;
  53. }
  54. CoinKernelData entity = _dicById[message.Input.GetId()];
  55. if (ReferenceEquals(entity, message.Input)) {
  56. return;
  57. }
  58. entity.Update(message.Input);
  59. var repository = NTMinerRoot.CreateServerRepository<CoinKernelData>();
  60. repository.Update(entity);
  61. VirtualRoot.RaiseEvent(new CoinKernelUpdatedEvent(message.Id, entity));
  62. });
  63. context.AddCmdPath<RemoveCoinKernelCommand>("移除币种内核", LogEnum.DevConsole,
  64. action: (message) => {
  65. InitOnece();
  66. if (message == null || message.EntityId == Guid.Empty) {
  67. throw new ArgumentNullException();
  68. }
  69. if (!_dicById.ContainsKey(message.EntityId)) {
  70. return;
  71. }
  72. CoinKernelData entity = _dicById[message.EntityId];
  73. _dicById.Remove(entity.Id);
  74. var repository = NTMinerRoot.CreateServerRepository<CoinKernelData>();
  75. repository.Remove(entity.Id);
  76. VirtualRoot.RaiseEvent(new CoinKernelRemovedEvent(message.Id, entity));
  77. if (context.CoinSet.TryGetCoin(entity.CoinId, out ICoin coin)) {
  78. List<Guid> toRemoves = new List<Guid>();
  79. IPool[] pools = context.PoolSet.AsEnumerable().Where(a => a.CoinId == coin.GetId()).ToArray();
  80. foreach (IPool pool in pools) {
  81. foreach (PoolKernelData poolKernel in context.PoolKernelSet.AsEnumerable().Where(a => a.PoolId == pool.GetId() && a.KernelId == entity.KernelId)) {
  82. toRemoves.Add(poolKernel.Id);
  83. }
  84. }
  85. foreach (Guid poolKernelId in toRemoves) {
  86. VirtualRoot.Execute(new RemovePoolKernelCommand(poolKernelId));
  87. }
  88. }
  89. });
  90. context.AddEventPath<FileWriterRemovedEvent>("移除文件书写器后移除引用关系", LogEnum.DevConsole,
  91. action: message => {
  92. var repository = NTMinerRoot.CreateServerRepository<CoinKernelData>();
  93. var entities = _dicById.Values.Where(a => a.FileWriterIds.Contains(message.Target.GetId())).ToArray();
  94. foreach (var entity in entities) {
  95. entity.FileWriterIds = new List<Guid>(entity.FileWriterIds.Where(a => a != message.Target.GetId()));
  96. repository.Update(entity);
  97. VirtualRoot.RaiseEvent(new CoinKernelUpdatedEvent(message.Id, entity));
  98. }
  99. });
  100. context.AddEventPath<FragmentWriterRemovedEvent>("移除命令行片段书写器后移除引用关系", LogEnum.DevConsole,
  101. action: message => {
  102. var repository = NTMinerRoot.CreateServerRepository<CoinKernelData>();
  103. var entities = _dicById.Values.Where(a => a.FragmentWriterIds.Contains(message.Target.GetId())).ToArray();
  104. foreach (var entity in entities) {
  105. entity.FragmentWriterIds = new List<Guid>(entity.FragmentWriterIds.Where(a => a != message.Target.GetId()));
  106. repository.Update(entity);
  107. VirtualRoot.RaiseEvent(new CoinKernelUpdatedEvent(message.Id, entity));
  108. }
  109. });
  110. }
  111. private bool _isInited = false;
  112. private readonly object _locker = new object();
  113. public int Count {
  114. get {
  115. InitOnece();
  116. return _dicById.Count;
  117. }
  118. }
  119. private void InitOnece() {
  120. if (_isInited) {
  121. return;
  122. }
  123. Init();
  124. }
  125. private void Init() {
  126. lock (_locker) {
  127. if (!_isInited) {
  128. var repository = NTMinerRoot.CreateServerRepository<CoinKernelData>();
  129. foreach (var item in repository.GetAll()) {
  130. if (!_dicById.ContainsKey(item.GetId())) {
  131. _dicById.Add(item.GetId(), item);
  132. }
  133. }
  134. _isInited = true;
  135. }
  136. }
  137. }
  138. public bool Contains(Guid kernelId) {
  139. InitOnece();
  140. return _dicById.ContainsKey(kernelId);
  141. }
  142. public bool TryGetCoinKernel(Guid kernelId, out ICoinKernel kernel) {
  143. InitOnece();
  144. var r = _dicById.TryGetValue(kernelId, out CoinKernelData k);
  145. kernel = k;
  146. return r;
  147. }
  148. public IEnumerable<ICoinKernel> AsEnumerable() {
  149. InitOnece();
  150. return _dicById.Values;
  151. }
  152. }
  153. }