Search in sources :

Example 1 with FileObjectSyncState

use of com.bonree.brfs.common.filesync.FileObjectSyncState in project BRFS by zhangnianli.

the class DefaultFileObjectSyncProcessor method process.

@Override
public boolean process(FileObjectSyncTask task) {
    FileObject file = task.file();
    LOG.info("start to synchronize file[{}]", file.node().getName());
    DuplicateNode[] nodeList = file.node().getDuplicateNodes();
    boolean syncAccomplished = true;
    List<FileObjectSyncState> fileStateList = getFileStateList(file.node());
    if (fileStateList.isEmpty()) {
        // 文件所在的所有磁盘节点都处于异常状态
        LOG.error("No available duplicate node is found to sync file[{}]", file.node().getName());
        if (task.isExpired()) {
            task.callback().timeout(file);
            return true;
        }
        return false;
    }
    if (fileStateList.size() != nodeList.length) {
        // 文件所在的所有磁盘节点中有部分不可用,这种情况先同步可用的磁盘节点信息
        LOG.warn("Not all duplicate nodes are available to sync file[{}]", file.node().getName());
        syncAccomplished = false;
    }
    long maxLength = -1;
    for (FileObjectSyncState state : fileStateList) {
        maxLength = Math.max(maxLength, state.getFileLength());
    }
    List<FileObjectSyncState> lack = new ArrayList<FileObjectSyncState>();
    List<FileObjectSyncState> full = new ArrayList<FileObjectSyncState>();
    for (FileObjectSyncState state : fileStateList) {
        if (state.getFileLength() != maxLength) {
            lack.add(state);
        } else {
            full.add(state);
        }
    }
    if (lack.isEmpty()) {
        if (syncAccomplished) {
            LOG.info("file[{}] is ok!", file.node().getName());
            task.callback().complete(file, maxLength);
            return true;
        } else {
            LOG.info("file[{}] is lack of some duplicate node!", file.node().getName());
            if (task.isExpired()) {
                LOG.info("file[{}] sync is expired!", file.node().getName());
                task.callback().timeout(file);
                return true;
            }
            return false;
        }
    } else {
        syncAccomplished &= doSynchronize(file.node(), maxLength, lack, full);
        if (syncAccomplished) {
            LOG.info("file[{}] sync is completed!", file.node().getName());
            task.callback().complete(file, maxLength);
            return true;
        } else {
            LOG.info("file[{}] sync is failed!", file.node().getName());
            if (task.isExpired()) {
                LOG.info("file[{}] sync is expired!", file.node().getName());
                task.callback().timeout(file);
                return true;
            }
            return false;
        }
    }
}
Also used : ArrayList(java.util.ArrayList) FileObjectSyncState(com.bonree.brfs.common.filesync.FileObjectSyncState) FileObject(com.bonree.brfs.duplication.datastream.file.FileObject) DuplicateNode(com.bonree.brfs.duplication.filenode.duplicates.DuplicateNode)

Example 2 with FileObjectSyncState

use of com.bonree.brfs.common.filesync.FileObjectSyncState in project BRFS by zhangnianli.

the class FileRecoveryMessageHandler method handleMessage.

@Override
public void handleMessage(BaseMessage baseMessage, ResponseWriter<BaseResponse> writer) {
    FileRecoveryMessage message = ProtoStuffUtils.deserialize(baseMessage.getBody(), FileRecoveryMessage.class);
    if (message == null) {
        LOG.error("decode recover message error");
        writer.write(new BaseResponse(ResponseCode.ERROR_PROTOCOL));
        return;
    }
    String filePath = null;
    try {
        filePath = context.getConcreteFilePath(message.getFilePath());
        LOG.info("starting recover file[{}]", filePath);
        Pair<RecordFileWriter, WriteWorker> binding = writerManager.getBinding(filePath, false);
        if (binding == null) {
            writer.write(new BaseResponse(ResponseCode.ERROR));
            return;
        }
        binding.first().position(fileFormater.absoluteOffset(message.getOffset()));
        byte[] bytes = null;
        for (String stateString : message.getSources()) {
            FileObjectSyncState state = SyncStateCodec.fromString(stateString);
            Service service = serviceManager.getServiceById(state.getServiceGroup(), state.getServiceId());
            if (service == null) {
                LOG.error("can not get service with[{}:{}]", state.getServiceGroup(), state.getServiceId());
                continue;
            }
            DiskNodeClient client = null;
            try {
                LOG.info("get data from{} to recover...", service);
                TcpClient<ReadObject, FileContentPart> readClient = clientGroup.createClient(new AsyncFileReaderCreateConfig() {

                    @Override
                    public SocketAddress remoteAddress() {
                        return new InetSocketAddress(service.getHost(), service.getExtraPort());
                    }

                    @Override
                    public int connectTimeoutMillis() {
                        return 3000;
                    }

                    @Override
                    public int maxPendingRead() {
                        return 0;
                    }
                }, ForkJoinPool.commonPool());
                client = new TcpDiskNodeClient(null, readClient);
                long lackBytes = state.getFileLength() - message.getOffset();
                CompletableFuture<byte[]> byteFuture = new CompletableFuture<byte[]>();
                ByteArrayOutputStream output = new ByteArrayOutputStream();
                client.readData(state.getFilePath(), message.getOffset(), (int) lackBytes, new ByteConsumer() {

                    @Override
                    public void error(Throwable e) {
                        byteFuture.completeExceptionally(e);
                    }

                    @Override
                    public void consume(byte[] bytes, boolean endOfConsume) {
                        try {
                            output.write(bytes);
                            if (endOfConsume) {
                                byteFuture.complete(output.toByteArray());
                                output.close();
                            }
                        } catch (Exception e) {
                            byteFuture.completeExceptionally(e);
                        }
                    }
                });
                bytes = byteFuture.get();
                if (bytes != null) {
                    LOG.info("read bytes length[{}], require[{}]", bytes.length, lackBytes);
                    break;
                }
            } catch (Exception e) {
                LOG.error("recover file[{}] error", filePath, e);
            } finally {
                CloseUtils.closeQuietly(client);
            }
        }
        if (bytes == null) {
            writer.write(new BaseResponse(ResponseCode.ERROR));
            return;
        }
        int offset = 0;
        int size = 0;
        while ((size = FileDecoder.getOffsets(offset, bytes)) > 0) {
            LOG.info("rewrite data[offset={}, size={}] to file[{}]", offset, size, filePath);
            binding.first().write(bytes, offset, size);
            offset += size;
            size = 0;
        }
        if (offset != bytes.length) {
            LOG.error("perhaps datas that being recoverd is not correct! get [{}], but recoverd[{}]", bytes.length, offset);
        }
        writer.write(new BaseResponse(ResponseCode.OK));
    } catch (Exception e) {
        LOG.error("recover file[{}] error", filePath, e);
        writer.write(new BaseResponse(ResponseCode.ERROR));
    }
}
Also used : InetSocketAddress(java.net.InetSocketAddress) TcpDiskNodeClient(com.bonree.brfs.disknode.client.TcpDiskNodeClient) DiskNodeClient(com.bonree.brfs.disknode.client.DiskNodeClient) BaseResponse(com.bonree.brfs.common.net.tcp.BaseResponse) ByteConsumer(com.bonree.brfs.disknode.client.DiskNodeClient.ByteConsumer) CompletableFuture(java.util.concurrent.CompletableFuture) RecordFileWriter(com.bonree.brfs.disknode.data.write.RecordFileWriter) FileContentPart(com.bonree.brfs.common.net.tcp.file.client.FileContentPart) AsyncFileReaderCreateConfig(com.bonree.brfs.common.net.tcp.file.client.AsyncFileReaderCreateConfig) SocketAddress(java.net.SocketAddress) InetSocketAddress(java.net.InetSocketAddress) FileObjectSyncState(com.bonree.brfs.common.filesync.FileObjectSyncState) Service(com.bonree.brfs.common.service.Service) ByteArrayOutputStream(java.io.ByteArrayOutputStream) TcpDiskNodeClient(com.bonree.brfs.disknode.client.TcpDiskNodeClient) ReadObject(com.bonree.brfs.common.net.tcp.file.ReadObject) FileRecoveryMessage(com.bonree.brfs.disknode.server.tcp.handler.data.FileRecoveryMessage) WriteWorker(com.bonree.brfs.disknode.data.write.worker.WriteWorker)

Example 3 with FileObjectSyncState

use of com.bonree.brfs.common.filesync.FileObjectSyncState in project BRFS by zhangnianli.

the class RecoveryMessageHandler method handle.

@Override
public void handle(HttpMessage msg, HandleResultCallback callback) {
    HandleResult handleResult = new HandleResult();
    String filePath = null;
    try {
        filePath = context.getConcreteFilePath(msg.getPath());
        LOG.info("starting recover file[{}]", filePath);
        String lengthParam = msg.getParams().get("length");
        if (lengthParam == null) {
            handleResult.setSuccess(false);
            callback.completed(handleResult);
            return;
        }
        long fileLength = Long.parseLong(msg.getParams().get("length"));
        List<String> fullStates = Splitter.on(',').omitEmptyStrings().trimResults().splitToList(msg.getParams().get("fulls"));
        Pair<RecordFileWriter, WriteWorker> binding = writerManager.getBinding(filePath, false);
        if (binding == null) {
            handleResult.setSuccess(false);
            callback.completed(handleResult);
            return;
        }
        binding.first().position(fileFormater.absoluteOffset(fileLength));
        byte[] bytes = null;
        for (String stateString : fullStates) {
            FileObjectSyncState state = SyncStateCodec.fromString(stateString);
            Service service = serviceManager.getServiceById(state.getServiceGroup(), state.getServiceId());
            if (service == null) {
                LOG.error("can not get service with[{}:{}]", state.getServiceGroup(), state.getServiceId());
                continue;
            }
            DiskNodeClient client = null;
            try {
                LOG.info("get data from{} to recover...", service);
                client = new HttpDiskNodeClient(service.getHost(), service.getPort());
                long lackBytes = state.getFileLength() - fileLength;
                CompletableFuture<byte[]> byteFuture = new CompletableFuture<byte[]>();
                ByteArrayOutputStream output = new ByteArrayOutputStream();
                client.readData(state.getFilePath(), fileLength, (int) lackBytes, new ByteConsumer() {

                    @Override
                    public void error(Throwable e) {
                        byteFuture.completeExceptionally(e);
                    }

                    @Override
                    public void consume(byte[] bytes, boolean endOfConsume) {
                        try {
                            output.write(bytes);
                            if (endOfConsume) {
                                byteFuture.complete(output.toByteArray());
                                output.close();
                            }
                        } catch (Exception e) {
                            byteFuture.completeExceptionally(e);
                        }
                    }
                });
                bytes = byteFuture.get();
                if (bytes != null) {
                    LOG.info("read bytes length[{}], require[{}]", bytes.length, lackBytes);
                    break;
                }
            } catch (Exception e) {
                LOG.error("recover file[{}] error", filePath, e);
            } finally {
                CloseUtils.closeQuietly(client);
            }
        }
        if (bytes == null) {
            handleResult.setSuccess(false);
            callback.completed(handleResult);
            return;
        }
        int offset = 0;
        int size = 0;
        while ((size = FileDecoder.getOffsets(offset, bytes)) > 0) {
            LOG.info("rewrite data[offset={}, size={}] to file[{}]", offset, size, filePath);
            binding.first().write(bytes, offset, size);
            offset += size;
            size = 0;
        }
        if (offset != bytes.length) {
            LOG.error("perhaps datas that being recoverd is not correct! get [{}], but recoverd[{}]", bytes.length, offset);
        }
        handleResult.setSuccess(true);
    } catch (Exception e) {
        LOG.error("recover file[{}] error", filePath, e);
        handleResult.setSuccess(false);
    } finally {
        callback.completed(handleResult);
    }
}
Also used : HttpDiskNodeClient(com.bonree.brfs.disknode.client.HttpDiskNodeClient) FileObjectSyncState(com.bonree.brfs.common.filesync.FileObjectSyncState) Service(com.bonree.brfs.common.service.Service) HandleResult(com.bonree.brfs.common.net.http.HandleResult) ByteArrayOutputStream(java.io.ByteArrayOutputStream) DiskNodeClient(com.bonree.brfs.disknode.client.DiskNodeClient) HttpDiskNodeClient(com.bonree.brfs.disknode.client.HttpDiskNodeClient) ByteConsumer(com.bonree.brfs.disknode.client.DiskNodeClient.ByteConsumer) CompletableFuture(java.util.concurrent.CompletableFuture) RecordFileWriter(com.bonree.brfs.disknode.data.write.RecordFileWriter) WriteWorker(com.bonree.brfs.disknode.data.write.worker.WriteWorker)

Example 4 with FileObjectSyncState

use of com.bonree.brfs.common.filesync.FileObjectSyncState in project BRFS by zhangnianli.

the class DefaultFileObjectSyncProcessor method getFileStateList.

private List<FileObjectSyncState> getFileStateList(FileNode fileNode) {
    List<FileObjectSyncState> fileStateList = new ArrayList<FileObjectSyncState>();
    for (DuplicateNode node : fileNode.getDuplicateNodes()) {
        DiskNodeConnection connection = connectionPool.getConnection(node.getGroup(), node.getId());
        if (connection == null || connection.getClient() == null) {
            LOG.error("duplication node[{}, {}] of [{}] is not available, that's maybe a trouble!", node.getGroup(), node.getId(), fileNode.getName());
            continue;
        }
        String filePath = pathMaker.buildPath(fileNode, node);
        LOG.info("checking---{}", filePath);
        long fileLength = connection.getClient().getFileLength(filePath);
        if (fileLength < 0) {
            LOG.error("duplication node[{}, {}] of [{}] can not get file length, that's maybe a trouble!", node.getGroup(), node.getId(), fileNode.getName());
            continue;
        }
        LOG.info("server{} -- {}", node.getId(), fileLength);
        fileStateList.add(new FileObjectSyncState(node.getGroup(), node.getId(), filePath, fileLength));
    }
    return fileStateList;
}
Also used : ArrayList(java.util.ArrayList) FileObjectSyncState(com.bonree.brfs.common.filesync.FileObjectSyncState) DuplicateNode(com.bonree.brfs.duplication.filenode.duplicates.DuplicateNode) DiskNodeConnection(com.bonree.brfs.duplication.datastream.connection.DiskNodeConnection)

Example 5 with FileObjectSyncState

use of com.bonree.brfs.common.filesync.FileObjectSyncState in project BRFS by zhangnianli.

the class DefaultFileObjectSyncProcessor method doSynchronize.

private boolean doSynchronize(FileNode fileNode, long correctLength, List<FileObjectSyncState> lacks, List<FileObjectSyncState> fulls) {
    List<String> fullStates = new ArrayList<String>();
    for (FileObjectSyncState state : fulls) {
        fullStates.add(SyncStateCodec.toString(state));
    }
    boolean allSynced = true;
    for (FileObjectSyncState state : lacks) {
        DiskNodeConnection connection = connectionPool.getConnection(state.getServiceGroup(), state.getServiceId());
        if (connection == null) {
            LOG.error("can not recover file[{}], because of lack of connection to service[{}, {}]", fileNode.getName(), state.getServiceGroup(), state.getServiceId());
            allSynced = false;
            continue;
        }
        DiskNodeClient client = connection.getClient();
        if (client == null) {
            allSynced = false;
            continue;
        }
        LOG.info("start synchronize file[{}] at data node[{}, {}]", fileNode.getName(), state.getServiceGroup(), state.getServiceId());
        if (!client.recover(state.getFilePath(), state.getFileLength(), fullStates)) {
            LOG.error("can not synchronize file[{}] at data node[{}, {}]", fileNode.getName(), state.getServiceGroup(), state.getServiceId());
            allSynced = false;
        }
    }
    return allSynced;
}
Also used : DiskNodeClient(com.bonree.brfs.disknode.client.DiskNodeClient) ArrayList(java.util.ArrayList) FileObjectSyncState(com.bonree.brfs.common.filesync.FileObjectSyncState) DiskNodeConnection(com.bonree.brfs.duplication.datastream.connection.DiskNodeConnection)

Aggregations

FileObjectSyncState (com.bonree.brfs.common.filesync.FileObjectSyncState)5 DiskNodeClient (com.bonree.brfs.disknode.client.DiskNodeClient)3 ArrayList (java.util.ArrayList)3 Service (com.bonree.brfs.common.service.Service)2 ByteConsumer (com.bonree.brfs.disknode.client.DiskNodeClient.ByteConsumer)2 RecordFileWriter (com.bonree.brfs.disknode.data.write.RecordFileWriter)2 WriteWorker (com.bonree.brfs.disknode.data.write.worker.WriteWorker)2 DiskNodeConnection (com.bonree.brfs.duplication.datastream.connection.DiskNodeConnection)2 DuplicateNode (com.bonree.brfs.duplication.filenode.duplicates.DuplicateNode)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 HandleResult (com.bonree.brfs.common.net.http.HandleResult)1 BaseResponse (com.bonree.brfs.common.net.tcp.BaseResponse)1 ReadObject (com.bonree.brfs.common.net.tcp.file.ReadObject)1 AsyncFileReaderCreateConfig (com.bonree.brfs.common.net.tcp.file.client.AsyncFileReaderCreateConfig)1 FileContentPart (com.bonree.brfs.common.net.tcp.file.client.FileContentPart)1 HttpDiskNodeClient (com.bonree.brfs.disknode.client.HttpDiskNodeClient)1 TcpDiskNodeClient (com.bonree.brfs.disknode.client.TcpDiskNodeClient)1 FileRecoveryMessage (com.bonree.brfs.disknode.server.tcp.handler.data.FileRecoveryMessage)1 FileObject (com.bonree.brfs.duplication.datastream.file.FileObject)1