private long[] GetOnlineServersWithBlock(long blockId) { long[] servers; // Note; we perform these operations inside a lock because we may need to // provision servers to contain certain blocks which requires a database // update. lock (blockDbWriteLock) { // Create a transaction ITransaction transaction = blockDatabase.CreateTransaction(); try { // Get the map, BlockServerTable blockServerTable = new BlockServerTable(transaction.GetFile(BlockServerKey, FileAccess.ReadWrite)); // Get the servers list, servers = blockServerTable[blockId]; // If the list is empty, if (servers.Length == 0) { // Provision servers to contain the block, servers = AllocateOnlineServerNodesForBlock(blockId); // Did we allocate any servers for this block? if (servers.Length > 0) { // Put the servers in the map, for (int i = 0; i < servers.Length; ++i) blockServerTable.Add(blockId, servers[i]); // Commit and check point the update, blockDatabase.Publish(transaction); blockDatabase.CheckPoint(); } } } finally { blockDatabase.Dispose(transaction); } } return servers; }
private void RegisterBlockServer(IServiceAddress serviceAddress) { // Open a connection with the block service, IMessageProcessor processor = connector.Connect(serviceAddress, ServiceType.Block); // Lock the block service with this manager RequestMessage request = new RequestMessage("bindWithManager"); request.Arguments.Add(address); Message response = processor.Process(request); if (response.HasError) throw new ApplicationException(response.ErrorMessage); // Get the block set report from the service, request = new RequestMessage("blockSetReport"); response = processor.Process(request); if (response.HasError) throw new ApplicationException(response.ErrorMessage); long serverGuid = response.Arguments[0].ToInt64(); long[] blockIdList = (long[])response.Arguments[1].Value; // Create a transaction lock (blockDbWriteLock) { ITransaction transaction = blockDatabase.CreateTransaction(); try { // Get the map, BlockServerTable blockServerTable = new BlockServerTable(transaction.GetFile(BlockServerKey, FileAccess.ReadWrite)); int actualAdded = 0; // Read until the end int sz = blockIdList.Length; // Put each block item into the database, for (int i = 0; i < sz; ++i) { long block_id = blockIdList[i]; bool added = blockServerTable.Add(block_id, serverGuid); if (added) { // TODO: Check if a service is adding polluted blocks into the // network via checksum, ++actualAdded; } } if (actualAdded > 0) { // Commit and check point the update, blockDatabase.Publish(transaction); blockDatabase.CheckPoint(); } } finally { blockDatabase.Dispose(transaction); } } BlockServerInfo blockServer = new BlockServerInfo(serverGuid, serviceAddress, ServiceStatus.Up); // Add it to the map lock (blockServersMap) { blockServersMap[serverGuid] = blockServer; blockServers.Add(blockServer); PersistBlockServers(blockServers); } // Update the address space end variable, UpdateAddressSpaceEnd(); }
private void AddBlockServerMapping(long blockId, long serverGuid) { lock (blockDbWriteLock) { // Create a transaction ITransaction transaction = blockDatabase.CreateTransaction(); try { // Get the map, BlockServerTable blockServerTable = new BlockServerTable(transaction.GetFile(BlockServerKey, FileAccess.Write)); // Make the block -> service map blockServerTable.Add(blockId, serverGuid); // Commit and check point the update, blockDatabase.Publish(transaction); blockDatabase.CheckPoint(); } finally { blockDatabase.Dispose(transaction); } } }