internal void ReportToLeader(object obj) { var replacedServer = (string)obj; while (true) { try { var channel = new Channel(this.leaderName, Service.PortNumber); // Advertise yourself channel.WriteUInt32((uint)OpCodes.AdvertiseService); channel.WriteString(this.ownName); channel.WriteString(replacedServer); channel.Flush(); // Receive a list of the partitions and cells the leader expects this Server to have var neededCells = new List<string>(); int resp = channel.ReadInt32(); if (resp == -2) { throw new Exception(string.Format("{0} is not a leader", this.leaderName)); } else if (resp == -3) { throw new Exception(string.Format("{0} is not offline", replacedServer)); } for (int i = 0; i < resp; i++) { var storeID = new Guid(channel.ReadBytes()); var partID = channel.ReadInt32(); var numParts = channel.ReadInt32(); var numReplicas = channel.ReadInt32(); var numPartitionBits = channel.ReadInt32(); var numRelativeBits = channel.ReadInt32(); var replicas = new string[numReplicas]; for (int j = 0; j < numReplicas; j++) { replicas[j] = channel.ReadString(); } var spid = new SPID(storeID, partID); var ping = new Partitioning(numParts, numReplicas, numPartitionBits, numRelativeBits); var numEpochs = channel.ReadInt32(); var cells = new List<Cell>(); for (int j = 0; j < numEpochs; j++) { var name = Cell.Name(spid, channel.ReadInt32()); neededCells.Add(name); cells.Add(this.LoadCell(name, replicas)); } // Load the partition. var part = new Partition(spid, ping, cells); lock (this.partitions) { this.partitions[spid] = part; } } // Delete all superfluous cell files on this Server var cellFileRegex = new Regex(Cell.NamePattern, RegexOptions.IgnoreCase); foreach (var x in Directory.GetFiles(Directory.GetCurrentDirectory()) .Select(x => Path.GetFileName(x)) .Where(x => cellFileRegex.IsMatch(x)) .Except(neededCells)) { File.Delete(x); } // Inform leader that everything is ready. this.readyForService = true; channel.WriteInt32(9999); channel.Flush(); var noResp = channel.ReadInt32(); throw new Exception("Received unexpected message from leader"); } catch (SocketException) { this.readyForService = false; this.partitions.Clear(); Thread.Sleep(1000); } } }
internal static IEnumerable<Tuple<byte[], byte[][]>> ReceiveLinks(Channel channel) { for (; ; ) { var page = channel.ReadBytes(); if (page == null) break; var n = channel.ReadInt32(); var links = new byte[n][]; for (int i = 0; i < n; i++) { links[i] = channel.ReadBytes(); } yield return new Tuple<byte[], byte[][]>(page, links); } }
internal static IEnumerable<byte[]> ReceiveUrls(Channel channel) { for (; ; ) { byte[] urlBytes = channel.ReadBytes(); if (urlBytes == null) break; yield return urlBytes; } }
public StoreInfo[] ListStores() { while (true) { try { var leader = new Channel(this.leaderName, Service.PortNumber); leader.WriteUInt32((uint)OpCodes.ListStores); leader.Flush(); int n = leader.ReadInt32(); var res = new StoreInfo[n]; for (int i = 0; i < n; i++) { var storeID = new Guid(leader.ReadBytes()); var friendlyName = leader.ReadString(); var numPartitions = leader.ReadInt32(); var numReplicas = leader.ReadInt32(); var numPartitionBits = leader.ReadInt32(); var numRelativeBits = leader.ReadInt32(); var isSealed = leader.ReadBoolean(); var isAvailable = leader.ReadBoolean(); res[i] = new StoreInfo(storeID, friendlyName, numPartitions, numReplicas, numPartitionBits, numRelativeBits, isSealed, isAvailable); } leader.Close(); return res; } catch (SocketException) { Thread.Sleep(5000); // sleep and then try again } } }