channel状态

typedef enum {
        CS_NEW,
        CS_INIT,
        CS_ROUTING,
        CS_SOFT_EXECUTE,
        CS_EXECUTE,
        CS_EXCHANGE_MEDIA,
        CS_PARK,
        CS_CONSUME_MEDIA,
        CS_HIBERNATE,
        CS_RESET,
        CS_HANGUP,
        CS_REPORTING,
        CS_DESTROY,
        CS_NONE
} switch_channel_state_t;
 

@Slf4j @Component public class StompMsgHandlerServiceGrpcClient{ /** * 清除断联 Channel 阈值 */ private static final int THRESHOLD = 10; private static final Integer GRPC_PORT = 8850; private final Map<String, Integer> channelCount = new ConcurrentHashMap<>(); private final ConcurrentHashMap<String, ManagedChannel> channelMap = new ConcurrentHashMap<>(); /** * 获取或创建 Channel */ public ManagedChannel getChannel(String ip, Integer port) { if (ip == null || port == null) { return null; } String key = ip + ":" + port; ManagedChannel channel = channelMap.get(key); if (channel != null) { return channel; } NettyChannelBuilder managedChannelBuilder; try { managedChannelBuilder = NettyChannelBuilder.forAddress(ip, port); } catch (Exception e) { log.error("Fail to create gRPC channel for {}, {}", ip, port); return null; } channel = managedChannelBuilder.usePlaintext() .disableRetry() .build(); channelMap.put(key, channel); watchConnectivityState(key, channel); return channel; } public void removeChannel(String ip, Integer port) { String key = ip + ":" + port; channelMap.remove(key); } public void handleStompMsg(EventWithInfo event) { Set<String> ipSet = event.getRouteInfo().values().stream().flatMap(Set::stream).collect(Collectors.toSet()); ipSet.forEach(ip -> { ManagedChannel channel = getChannel(ip, GRPC_PORT); if (channel == null || channel.isShutdown() || channel.isTerminated()) { log.error("channel is shutdown or terminated"); removeChannel(ip, GRPC_PORT); return; } StompMsgHandleServiceStub stub = StompMsgHandleServiceGrpc.newStub(channel); WsPushGrpcRequest request = WsPushGrpcRequest.newBuilder().setValue(JsonUtils.bean2Json(event.getEvent())).build(); stub.handleStompMsg(request, new StreamObserver<Empty>() { @Override public void onNext(Empty empty) { // 收到响应后,不做任何处理 log.info("msg send success"); } @Override public void onError(Throwable throwable) { log.error("msg send error, cause: {}", throwable.getMessage()); } @Override public void onCompleted() { log.info("msg send completed"); } });}); } @PreDestroy public void clearChannelMap() { channelMap.forEach((key, channel) -> channel.shutdown()); } /** * 追踪channel状态变化,失败达到阈值则关闭 * * @param name channel name * @param channel channel */ private void watchConnectivityState(String name, ManagedChannel channel) { ConnectivityState state = channel.getState(false); if (state == ConnectivityState.TRANSIENT_FAILURE) { Integer integer = channelCount.get(name); if (integer == null) { channelCount.put(name, 1); } else { if (integer > THRESHOLD) { // 清除channel channelMap.remove(name); channelCount.remove(name); channel.shutdownNow(); } else { // 增加计数 channelCount.put(name, ++integer); } } } if (state != ConnectivityState.SHUTDOWN) { channel.notifyWhenStateChanged(state, () -> watchConnectivityState(name, channel)); } } } 请你使用Mock为这个类编写单元测试,要求测试覆盖率高,80%以上
最新发布
11-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值