Code review comment: if allbackends == null ,then nptr throws

Code under review:
private void publishVersion() {
        GlobalTransactionMgr globalTransactionMgr = Catalog.getCurrentGlobalTransactionMgr();
        List<TransactionState> readyTransactionStates = globalTransactionMgr.getReadyToPublishTransactions();
        if (readyTransactionStates == null || readyTransactionStates.isEmpty()) {
            return;
        }
        
        
        
        
        
        List<Long> allBackends = Catalog.getCurrentSystemInfo().getBackendIds(false);
        if (allBackends.isEmpty()) {
            LOG.warn("some transaction state need to publish, but no backend exists");
            return;
        }
        
        AgentBatchTask batchTask = new AgentBatchTask();
        
        for (TransactionState transactionState : readyTransactionStates) {
            if (transactionState.hasSendTask()) {
                continue;
            }
            List<PartitionCommitInfo> partitionCommitInfos = new ArrayList<>();
            for (TableCommitInfo tableCommitInfo : transactionState.getIdToTableCommitInfos().values()) {
                partitionCommitInfos.addAll(tableCommitInfo.getIdToPartitionCommitInfo().values());
            }
            List<TPartitionVersionInfo> partitionVersionInfos = new ArrayList<>(partitionCommitInfos.size());
            for (PartitionCommitInfo commitInfo : partitionCommitInfos) {
                TPartitionVersionInfo versionInfo = new TPartitionVersionInfo(commitInfo.getPartitionId(), 
                        commitInfo.getVersion(), 
                        commitInfo.getVersionHash());
                partitionVersionInfos.add(versionInfo);
                if (LOG.isDebugEnabled()) {
                    LOG.debug("try to publish version info partitionid [{}], version [{}], version hash [{}]", 
                            commitInfo.getPartitionId(), 
                            commitInfo.getVersion(), 
                            commitInfo.getVersionHash());
                }
            }
            Set<Long> publishBackends = transactionState.getPublishVersionTasks().keySet();
            if (publishBackends.isEmpty()) {
                
                publishBackends = Sets.newHashSet();
                
                
                publishBackends.addAll(allBackends);
            }
            for (long backendId : publishBackends) {
                PublishVersionTask task = new PublishVersionTask(backendId, 
                                                                 transactionState.getTransactionId(), 
                                                                 partitionVersionInfos);
                
                
                AgentTaskQueue.addTask(task);
                batchTask.addTask(task);
                transactionState.addPublishVersionTask(backendId, task);
            }
            transactionState.setHasSendTask(true);
        }
        if (!batchTask.getAllTasks().isEmpty()) {
            AgentTaskExecutor.submit(batchTask);
        }
        
        TabletInvertedIndex tabletInvertedIndex = Catalog.getCurrentInvertedIndex();
        
        long currentTime = System.currentTimeMillis();
        for (TransactionState transactionState : readyTransactionStates) {
            if (transactionState.getPublishVersionTime() - currentTime < Config.publish_version_interval_millis * 2) {
                
                continue;
            }
            Map<Long, PublishVersionTask> transTasks = transactionState.getPublishVersionTasks();
            Set<Replica> transErrorReplicas = Sets.newHashSet();
            for (PublishVersionTask publishVersionTask : transTasks.values()) {
                if (publishVersionTask.isFinished()) {
                    
                    
                    List<Long> errorTablets = publishVersionTask.getErrorTablets();
                    if (errorTablets == null || errorTablets.isEmpty()) {
                        continue;
                    } else {
                        for (long tabletId : errorTablets) {
                            
                            Replica replica = tabletInvertedIndex.getReplica(tabletId, publishVersionTask.getBackendId());
                            transErrorReplicas.add(replica);
                        }
                    }
                } else {
                    
                    List<TPartitionVersionInfo> versionInfos = publishVersionTask.getPartitionVersionInfos();
                    Set<Long> errorPartitionIds = Sets.newHashSet();
                    for (TPartitionVersionInfo versionInfo : versionInfos) {
                        errorPartitionIds.add(versionInfo.getPartition_id());
                    }
                    if (errorPartitionIds.isEmpty()) {
                        continue;
                    }
                    List<Long> tabletIds = tabletInvertedIndex.getTabletIdsByBackendId(publishVersionTask.getBackendId());
                    for (long tabletId : tabletIds) {
                        long partitionId = tabletInvertedIndex.getPartitionId(tabletId);
                        if (errorPartitionIds.contains(partitionId)) {
                            Replica replica = tabletInvertedIndex.getReplica(tabletId, publishVersionTask.getBackendId());
                            transErrorReplicas.add(replica);
                        }
                    }
                }
            }
            
            long timeoutMillis = Math.min(Config.publish_version_timeout_second * transTasks.size() * 1000, 10000);
            
            timeoutMillis = Math.max(timeoutMillis, 3000);
            
            
            
            int normalReplicasNotRespond = 0;
            Set<Long> allErrorReplicas = Sets.newHashSet();
            for (Replica replica : transErrorReplicas) {
                allErrorReplicas.add(replica.getId());
                if (replica.getState() != ReplicaState.CLONE 
                        && replica.getLastFailedVersion() < 1) {
                    ++normalReplicasNotRespond;
                }
            }
            if (normalReplicasNotRespond == 0 
                    || System.currentTimeMillis() - transactionState.getPublishVersionTime() > timeoutMillis) {
                LOG.debug("transTask num {}, error replica id num {}", transTasks.size(), transErrorReplicas.size());
                globalTransactionMgr.finishTransaction(transactionState.getTransactionId(), allErrorReplicas);
                if (transactionState.getTransactionStatus() != TransactionStatus.VISIBLE) {
                    
                    
                    transactionState.updateSendTaskTime();
                    LOG.debug("publish version for transation {} failed, has {} error replicas during publish", 
                            transactionState, transErrorReplicas.size());
                }
            }
            if (transactionState.getTransactionStatus() == TransactionStatus.VISIBLE) {
                for (PublishVersionTask task : transactionState.getPublishVersionTasks().values()) {
                    AgentTaskQueue.removeTask(task.getBackendId(), TTaskType.PUBLISH_VERSION, task.getSignature());
                }
            }
        }
    }

Line commented on: return;

Revised code:
private void publishVersion() {
        GlobalTransactionMgr globalTransactionMgr = Catalog.getCurrentGlobalTransactionMgr();
        List<TransactionState> readyTransactionStates = globalTransactionMgr.getReadyToPublishTransactions();
        if (readyTransactionStates == null || readyTransactionStates.isEmpty()) {
            return;
        }
        
        
        
        
        
        List<Long> allBackends = Catalog.getCurrentSystemInfo().getBackendIds(false);
        if (allBackends.isEmpty()) {
            LOG.warn("some transaction state need to publish, but no backend exists");
            return;
        }
        
        AgentBatchTask batchTask = new AgentBatchTask();
        
        for (TransactionState transactionState : readyTransactionStates) {
            if (transactionState.hasSendTask()) {
                continue;
            }
            List<PartitionCommitInfo> partitionCommitInfos = new ArrayList<>();
            for (TableCommitInfo tableCommitInfo : transactionState.getIdToTableCommitInfos().values()) {
                partitionCommitInfos.addAll(tableCommitInfo.getIdToPartitionCommitInfo().values());
            }
            List<TPartitionVersionInfo> partitionVersionInfos = new ArrayList<>(partitionCommitInfos.size());
            for (PartitionCommitInfo commitInfo : partitionCommitInfos) {
                TPartitionVersionInfo versionInfo = new TPartitionVersionInfo(commitInfo.getPartitionId(), 
                        commitInfo.getVersion(), 
                        commitInfo.getVersionHash());
                partitionVersionInfos.add(versionInfo);
                if (LOG.isDebugEnabled()) {
                    LOG.debug("try to publish version info partitionid [{}], version [{}], version hash [{}]", 
                            commitInfo.getPartitionId(), 
                            commitInfo.getVersion(), 
                            commitInfo.getVersionHash());
                }
            }
            Set<Long> publishBackends = transactionState.getPublishVersionTasks().keySet();
            if (publishBackends.isEmpty()) {
                
                publishBackends = Sets.newHashSet();
                
                
                publishBackends.addAll(allBackends);
            }
            for (long backendId : publishBackends) {
                PublishVersionTask task = new PublishVersionTask(backendId, 
                                                                 transactionState.getTransactionId(), 
                                                                 partitionVersionInfos);
                
                
                AgentTaskQueue.addTask(task);
                batchTask.addTask(task);
                transactionState.addPublishVersionTask(backendId, task);
            }
            transactionState.setHasSendTask(true);
        }
        if (!batchTask.getAllTasks().isEmpty()) {
            AgentTaskExecutor.submit(batchTask);
        }
        
        TabletInvertedIndex tabletInvertedIndex = Catalog.getCurrentInvertedIndex();
        
        long currentTime = System.currentTimeMillis();
        for (TransactionState transactionState : readyTransactionStates) {
            if (currentTime - transactionState.getPublishVersionTime() < Config.publish_version_interval_millis * 2) {
                
                continue;
            }
            Map<Long, PublishVersionTask> transTasks = transactionState.getPublishVersionTasks();
            Set<Replica> transErrorReplicas = Sets.newHashSet();
            for (PublishVersionTask publishVersionTask : transTasks.values()) {
                if (publishVersionTask.isFinished()) {
                    
                    
                    List<Long> errorTablets = publishVersionTask.getErrorTablets();
                    if (errorTablets == null || errorTablets.isEmpty()) {
                        continue;
                    } else {
                        for (long tabletId : errorTablets) {
                            
                            Replica replica = tabletInvertedIndex.getReplica(tabletId, publishVersionTask.getBackendId());
                            transErrorReplicas.add(replica);
                        }
                    }
                } else {
                    
                    List<TPartitionVersionInfo> versionInfos = publishVersionTask.getPartitionVersionInfos();
                    Set<Long> errorPartitionIds = Sets.newHashSet();
                    for (TPartitionVersionInfo versionInfo : versionInfos) {
                        errorPartitionIds.add(versionInfo.getPartition_id());
                    }
                    if (errorPartitionIds.isEmpty()) {
                        continue;
                    }
                    List<Long> tabletIds = tabletInvertedIndex.getTabletIdsByBackendId(publishVersionTask.getBackendId());
                    for (long tabletId : tabletIds) {
                        long partitionId = tabletInvertedIndex.getPartitionId(tabletId);
                        if (errorPartitionIds.contains(partitionId)) {
                            Replica replica = tabletInvertedIndex.getReplica(tabletId, publishVersionTask.getBackendId());
                            transErrorReplicas.add(replica);
                        }
                    }
                }
            }
            
            long timeoutMillis = Math.min(Config.publish_version_timeout_second * transTasks.size() * 1000, 10000);
            
            timeoutMillis = Math.max(timeoutMillis, 3000);
            
            
            
            int normalReplicasNotRespond = 0;
            Set<Long> allErrorReplicas = Sets.newHashSet();
            for (Replica replica : transErrorReplicas) {
                allErrorReplicas.add(replica.getId());
                if (replica.getState() != ReplicaState.CLONE 
                        && replica.getLastFailedVersion() < 1) {
                    ++normalReplicasNotRespond;
                }
            }
            if (normalReplicasNotRespond == 0 
                    || System.currentTimeMillis() - transactionState.getPublishVersionTime() > timeoutMillis) {
                LOG.debug("transTask num {}, error replica id num {}", transTasks.size(), transErrorReplicas.size());
                globalTransactionMgr.finishTransaction(transactionState.getTransactionId(), allErrorReplicas);
                if (transactionState.getTransactionStatus() != TransactionStatus.VISIBLE) {
                    
                    
                    transactionState.updateSendTaskTime();
                    LOG.debug("publish version for transation {} failed, has {} error replicas during publish", 
                            transactionState, transErrorReplicas.size());
                }
            }
            if (transactionState.getTransactionStatus() == TransactionStatus.VISIBLE) {
                for (PublishVersionTask task : transactionState.getPublishVersionTasks().values()) {
                    AgentTaskQueue.removeTask(task.getBackendId(), TTaskType.PUBLISH_VERSION, task.getSignature());
                }
            }
        }
    }