Spring Boot GRPC Отправить несколько запросов параллельно с помощью завершаемой FUTURE (безопасность потока)JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Spring Boot GRPC Отправить несколько запросов параллельно с помощью завершаемой FUTURE (безопасность потока)

Сообщение Anonymous »

Чтобы улучшить производительность, я использую java opplyblefuture для отправки параллельного запроса на сервере grpc . Я также использовал ehcache от Spring Boot, чтобы кэшировать модель возврата с сервера GRPC в течение 2 часов. Эта реализация кажется, что работает правильно, но я пытаюсь глубоко понять эту ситуацию. Убедитесь, что каждый призыв из Treeservice будет иметь свой собственный экземпляр, чтобы предотвратить несоответствие потока. Могу ли я использовать Singleton Scope? /> Что я могу улучшить при приведенном ниже поведении GRPC Parallel, запрашивающее, в случае ответа на задержку, обработки исключений или другого углового чехла, который мне нужно быть осторожным. Спасибо! < /P>
@Configuration
@RequiredArgsConstructor
public class GrpcStubConfig {

private final GrpcClientConfig grpcClientConfig;

@Bean(name = GRPC_MASTERDATA_EDITOR_MANAGED_CHANNEL_BEAN)
public ManagedChannel grpcManagedChannel() {
GrpcClientConfig.ServerConfig serverConfig = getServerConfig(GRPC_SERVER_MASTERDATA_EDITOR_MANAGER);
return ManagedChannelBuilder
.forAddress(serverConfig.getHost(), serverConfig.getPort())
.usePlaintext() // o .useTransportSecurity() se usi TLS
.build();
}

@Bean(IBeanQualifierCostants.GRPC_MASTERDATA_EDITOR_NODE_SERVICE_BLOCKING_STUB_BEAN)
public NodeServiceGrpc.NodeServiceBlockingStub nodeServiceBlockingStub(@Qualifier(GRPC_MASTERDATA_EDITOR_MANAGED_CHANNEL_BEAN) ManagedChannel channel) {
return NodeServiceGrpc.newBlockingStub(channel);
}

private GrpcClientConfig.ServerConfig getServerConfig(String serverName) {
GrpcClientConfig.ServerConfig serverConfig = grpcClientConfig.getServers().get(serverName);
if(serverConfig == null){
return new GrpcClientConfig.ServerConfig();
}
return serverConfig;
}
}
< /code>
nodegrpcclientserviceimpl.java
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@Slf4j
public class NodeGrpcClientServiceImpl implements NodeGrpcClientService {

private final NodeServiceGrpc.NodeServiceBlockingStub nodeServiceBlockingStub;
private static final Integer MASTER_DATA_EDITOR_TEMPLATE_ID = 18;

public NodeGrpcClientServiceImpl(@Qualifier(IBeanQualifierCostants.GRPC_MASTERDATA_EDITOR_NODE_SERVICE_BLOCKING_STUB_BEAN) NodeServiceGrpc.NodeServiceBlockingStub nodeServiceBlockingStub) {
this.nodeServiceBlockingStub = nodeServiceBlockingStub;
}

@Override
@Cacheable(value = IConfigConstants.GRPC_NODE_ATTRIBUTE_CACHE)
public NodeResponseDTO searchNodeByEntityType(NodeRequestDTO nodeRequestDTO) {

log.info("Searching node by nodeRequest: {} ", nodeRequestDTO);
NodeResponseDTO nodeResponseDTO = null;

try {

NodeRequest nodeRequest = NodeRequest.newBuilder()
.setIdEntity(nodeRequestDTO.getIdEntity())
.setIdEntityType(nodeRequestDTO.getIdEntityType())
.setAttributeType(nodeRequestDTO.getAttributeType())
.setTemplateId(MASTER_DATA_EDITOR_TEMPLATE_ID)
.build();

NodeResponse nodeResponse = nodeServiceBlockingStub.searchNodeByEntityType(nodeRequest);

if (nodeResponse!=null && StringUtils.isNotBlank(nodeResponse.getValue())) {
nodeResponseDTO = NodeResponseDTO.builder()
.value(nodeResponse.getValue())
.build();
}

}catch (io.grpc.StatusRuntimeException statusRuntimeException){
log.error("NodeGrpcClientServiceImpl:::Error while calling grpc api: {}", statusRuntimeException.getMessage(), statusRuntimeException);
}catch (Exception exception){
log.error("NodeGrpcClientServiceImpl:::Error while calling grpc api: {}", exception.getMessage(), exception);
}

log.info("Received response: {}", nodeResponseDTO);
return nodeResponseDTO;
}

}
< /code>
treeserviceimpl.java
@Slf4j
@Service
public class TreeServiceImpl implements TreeService {

private static final TreeNodeMapper treeNodeMapper = TreeNodeMapper.INSTANCE;
private final TreeRepository treeRepository;
private static final String NODE_ATTRIBUTE_TYPE = "IMG_URI";

private final ExecutorService firstLevelEventManagerTreeExecutorService;
private final NodeGrpcClientService nodeGrpcClientService;

public TreeServiceImpl(TreeRepository treeRepository, @Qualifier(IBeanQualifierCostants.FIRST_LEVEL_EVENT_MANAGER_TREE_EXECUTOR_SERVICE) ExecutorService firstLevelEventManagerTreeExecutorService,
NodeGrpcClientService nodeGrpcClientService) {
this.treeRepository = treeRepository;
this.firstLevelEventManagerTreeExecutorService = firstLevelEventManagerTreeExecutorService;
this.secondLevelEventManagerTreeExecutorService = secondLevelEventManagerTreeExecutorService;
this.thirdLevelEventManagerTreeExecutorService = thirdLevelEventManagerTreeExecutorService;
this.nodeGrpcClientService = nodeGrpcClientService;
}

@Override
public List getFirstLevelEventManagerTree(LocaleRequest localeRequest) {

List firstLevelEventManagerTree = --> get data from Repository
List completableFutureList = new ArrayList();

try {
manageImageNodeAttributesOnEventManagerTree(firstLevelEventManagerTree,completableFutureList,firstLevelEventManagerTreeExecutorService);
waitOnCompletableFutureList(completableFutureList);
} catch (Exception exception) {
log.error("TreeServiceImpl:::Error while processing first level event manager tree: {}", exception.getMessage(), exception);
}

log.info("First level event manager tree: {}", firstLevelEventManagerTree);
return treeNodeMapper.toDTOList(firstLevelEventManagerTree);

}

private void manageImageNodeAttributesOnEventManagerTree(List eventManagerTree, List completableFutureList, ExecutorService eventManagerTreeExecutorService) {
if(CollectionUtils.isNotEmpty(eventManagerTree)){
for(TreeNodeEntity treeNodeEntity : eventManagerTree) {
completableFutureList.add(CompletableFuture.runAsync(() -> {
fillImageNodeAttributesOnEventManagerTree(treeNodeEntity);
}, eventManagerTreeExecutorService));
}
}
}

private void fillImageNodeAttributesOnEventManagerTree(TreeNodeEntity treeNodeEntity){
NodeResponseDTO nodeResponseDTO = nodeGrpcClientService.searchNodeByEntityType(
new NodeRequestDTO(treeNodeEntity.getId(), treeNodeEntity.getLeafType().name(), NODE_ATTRIBUTE_TYPE));
if(nodeResponseDTO !=null && StringUtils.isNotBlank(nodeResponseDTO.getValue())) {
log.info("TreeServiceImpl:::NodeResponseDTO found for entityId: {}, entityType: {}, attributeType: {}", treeNodeEntity.getId(), treeNodeEntity.getLeafType().name(), NODE_ATTRIBUTE_TYPE);
treeNodeEntity.setIcon(nodeResponseDTO.getValue());
} else {
log.warn("TreeServiceImpl:::NodeResponseDTO is null or value is empty for entityId: {}, entityType: {}, attributeType: {}", treeNodeEntity.getId(),treeNodeEntity.getLeafType().name(), NODE_ATTRIBUTE_TYPE);
}
}

private void waitOnCompletableFutureList(List completableFutureList) throws ExecutionException, InterruptedException {
CompletableFuture.allOf(completableFutureList.toArray(new CompletableFuture[0])).get();
}

}


Подробнее здесь: https://stackoverflow.com/questions/796 ... uture-thre
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»