Exemplo n.º 1
0
            private long SendBlockTo(BlockId blockId, IServiceAddress destAddress, long destServerId,
                                     IServiceAddress[] managerServers)
            {
                lock (service.processLock) {
                    long          processId = service.processIdSeq++;
                    SendBlockInfo info      = new SendBlockInfo(processId, blockId, destAddress, destServerId, managerServers);
                    // Schedule the process to happen immediately (or as immediately as
                    // possible).
                    new Timer(SendBlockToTask, info, 0, Timeout.Infinite);

                    return(processId);
                }
            }
Exemplo n.º 2
0
            private void SendBlockToTask(object state)
            {
                SendBlockInfo info = (SendBlockInfo)state;

                // Connect to the destination service address,
                IMessageProcessor p = service.Connector.Connect(info.Destination, ServiceType.Block);

                int blockType = service.DiscoverBlockType(info.BlockId);

                if (blockType == -1)
                {
                    return;
                }

                BlockData data = service.GetBlockData(info.BlockId, blockType);

                // If the data was not found, exit,
                if (!data.Exists)
                {
                    return;
                }

                try {
                    BlockContainer blockContainer = service.FetchBlockContainer(info.BlockId);
                    // If the block was written to less than 6 minutes ago, we don't allow
                    // the copy to happen,
                    if (!service.IsKnownStaticBlock(blockContainer))
                    {
                        // This will happen if this block server has not be notified
                        // recently by the managers the maximum block id they are managing.
                        service.Logger.Info(String.Format("Can't copy last block_id ( {0} ) on server, it's not a known static block.",
                                                          info.BlockId));
                        return;
                    }


                    IEnumerable <Message> inputStream;
                    Message ouputMessage;

                    // If the file does exist, push it over,
                    byte[] buf = new byte[16384];
                    int    pos = 0;
                    Stream fin = data.OpenRead();

                    while (true)
                    {
                        int read = fin.Read(buf, 0, buf.Length);
                        // Exit if we reached the end of the file,
                        if (read == 0)
                        {
                            break;
                        }

                        ouputMessage = new Message("sendBlockPart", info.BlockId, pos, blockType, buf, read);
                        // Process the message,
                        inputStream = p.Process(ouputMessage.AsStream());
                        // Get the input iterator,
                        foreach (Message m in inputStream)
                        {
                            if (m.HasError)
                            {
                                service.Logger.Info(String.Format("'sendBlockPart' command error: {0}", m.ErrorMessage));
                                return;
                            }
                        }

                        pos += read;
                    }

                    // Close,
                    fin.Close();

                    // Send the 'complete' command,
                    ouputMessage = new Message("sendBlockComplete", info.BlockId, blockType);
                    // Process the message,
                    inputStream = p.Process(ouputMessage.AsStream());
                    // Get the input iterator,
                    foreach (Message m in inputStream)
                    {
                        if (m.HasError)
                        {
                            service.Logger.Info(String.Format("'sendBlockCommand' command error: {0}", m.ErrorMessage));
                            return;
                        }
                    }

                    // Tell the manager server about this new block mapping,
                    ouputMessage = new Message("internalAddBlockServerMapping", info.BlockId, new long[] { info.DestinationServerId });
                    service.Logger.Info(String.Format("Adding block_id->server mapping ({0} -> {1})", info.BlockId,
                                                      info.DestinationServerId));

                    for (int n = 0; n < info.ManagerServers.Length; ++n)
                    {
                        // Process the message,
                        IMessageProcessor mp = service.Connector.Connect(info.ManagerServers[n], ServiceType.Manager);
                        inputStream = mp.Process(ouputMessage.AsStream());
                        // Get the input iterator,
                        foreach (Message m in inputStream)
                        {
                            if (m.HasError)
                            {
                                service.Logger.Info(String.Format("'internalAddBlockServerMapping' command error: @ {0} - {1}",
                                                                  info.ManagerServers[n], m.ErrorMessage));
                                break;
                            }
                        }
                    }
                } catch (IOException e) {
                    service.Logger.Info(e);
                }
            }