Search in sources :

Example 1 with RpcContext

use of io.seata.core.rpc.RpcContext in project seata by seata.

the class ChannelManager method getChannel.

/**
 * Gets get channel.
 *
 * @param resourceId Resource ID
 * @param clientId   Client ID - ApplicationId:IP:Port
 * @return Corresponding channel, NULL if not found.
 */
public static Channel getChannel(String resourceId, String clientId) {
    Channel resultChannel = null;
    String[] clientIdInfo = readClientId(clientId);
    if (clientIdInfo == null || clientIdInfo.length != 3) {
        throw new FrameworkException("Invalid Client ID: " + clientId);
    }
    String targetApplicationId = clientIdInfo[0];
    String targetIP = clientIdInfo[1];
    int targetPort = Integer.parseInt(clientIdInfo[2]);
    ConcurrentMap<String, ConcurrentMap<String, ConcurrentMap<Integer, RpcContext>>> applicationIdMap = RM_CHANNELS.get(resourceId);
    if (targetApplicationId == null || applicationIdMap == null || applicationIdMap.isEmpty()) {
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("No channel is available for resource[{}]", resourceId);
        }
        return null;
    }
    ConcurrentMap<String, ConcurrentMap<Integer, RpcContext>> ipMap = applicationIdMap.get(targetApplicationId);
    if (ipMap != null && !ipMap.isEmpty()) {
        // Firstly, try to find the original channel through which the branch was registered.
        ConcurrentMap<Integer, RpcContext> portMapOnTargetIP = ipMap.get(targetIP);
        if (portMapOnTargetIP != null && !portMapOnTargetIP.isEmpty()) {
            RpcContext exactRpcContext = portMapOnTargetIP.get(targetPort);
            if (exactRpcContext != null) {
                Channel channel = exactRpcContext.getChannel();
                if (channel.isActive()) {
                    resultChannel = channel;
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debug("Just got exactly the one {} for {}", channel, clientId);
                    }
                } else {
                    if (portMapOnTargetIP.remove(targetPort, exactRpcContext)) {
                        if (LOGGER.isInfoEnabled()) {
                            LOGGER.info("Removed inactive {}", channel);
                        }
                    }
                }
            }
            // The original channel was broken, try another one.
            if (resultChannel == null) {
                for (ConcurrentMap.Entry<Integer, RpcContext> portMapOnTargetIPEntry : portMapOnTargetIP.entrySet()) {
                    Channel channel = portMapOnTargetIPEntry.getValue().getChannel();
                    if (channel.isActive()) {
                        resultChannel = channel;
                        if (LOGGER.isInfoEnabled()) {
                            LOGGER.info("Choose {} on the same IP[{}] as alternative of {}", channel, targetIP, clientId);
                        }
                        break;
                    } else {
                        if (portMapOnTargetIP.remove(portMapOnTargetIPEntry.getKey(), portMapOnTargetIPEntry.getValue())) {
                            if (LOGGER.isInfoEnabled()) {
                                LOGGER.info("Removed inactive {}", channel);
                            }
                        }
                    }
                }
            }
        }
        // No channel on the this app node, try another one.
        if (resultChannel == null) {
            for (ConcurrentMap.Entry<String, ConcurrentMap<Integer, RpcContext>> ipMapEntry : ipMap.entrySet()) {
                if (ipMapEntry.getKey().equals(targetIP)) {
                    continue;
                }
                ConcurrentMap<Integer, RpcContext> portMapOnOtherIP = ipMapEntry.getValue();
                if (portMapOnOtherIP == null || portMapOnOtherIP.isEmpty()) {
                    continue;
                }
                for (ConcurrentMap.Entry<Integer, RpcContext> portMapOnOtherIPEntry : portMapOnOtherIP.entrySet()) {
                    Channel channel = portMapOnOtherIPEntry.getValue().getChannel();
                    if (channel.isActive()) {
                        resultChannel = channel;
                        if (LOGGER.isInfoEnabled()) {
                            LOGGER.info("Choose {} on the same application[{}] as alternative of {}", channel, targetApplicationId, clientId);
                        }
                        break;
                    } else {
                        if (portMapOnOtherIP.remove(portMapOnOtherIPEntry.getKey(), portMapOnOtherIPEntry.getValue())) {
                            if (LOGGER.isInfoEnabled()) {
                                LOGGER.info("Removed inactive {}", channel);
                            }
                        }
                    }
                }
                if (resultChannel != null) {
                    break;
                }
            }
        }
    }
    if (resultChannel == null) {
        resultChannel = tryOtherApp(applicationIdMap, targetApplicationId);
        if (resultChannel == null) {
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("No channel is available for resource[{}] as alternative of {}", resourceId, clientId);
            }
        } else {
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("Choose {} on the same resource[{}] as alternative of {}", resultChannel, resourceId, clientId);
            }
        }
    }
    return resultChannel;
}
Also used : FrameworkException(io.seata.common.exception.FrameworkException) Channel(io.netty.channel.Channel) ConcurrentMap(java.util.concurrent.ConcurrentMap) RpcContext(io.seata.core.rpc.RpcContext)

Example 2 with RpcContext

use of io.seata.core.rpc.RpcContext in project seata by seata.

the class ChannelManager method getChannelFromSameClientMap.

private static Channel getChannelFromSameClientMap(Map<Integer, RpcContext> clientChannelMap, int exclusivePort) {
    if (clientChannelMap != null && !clientChannelMap.isEmpty()) {
        for (ConcurrentMap.Entry<Integer, RpcContext> entry : clientChannelMap.entrySet()) {
            if (entry.getKey() == exclusivePort) {
                clientChannelMap.remove(entry.getKey());
                continue;
            }
            Channel channel = entry.getValue().getChannel();
            if (channel.isActive()) {
                return channel;
            }
            clientChannelMap.remove(entry.getKey());
        }
    }
    return null;
}
Also used : RpcContext(io.seata.core.rpc.RpcContext) Channel(io.netty.channel.Channel) ConcurrentMap(java.util.concurrent.ConcurrentMap)

Example 3 with RpcContext

use of io.seata.core.rpc.RpcContext in project seata by seata.

the class DefaultCoordinatorMetricsTest method test.

@Test
public void test() throws IOException, TransactionException, InterruptedException {
    SessionHolder.init(null);
    DefaultCoordinator coordinator = new DefaultCoordinator(new MockServerMessageSender());
    coordinator.init();
    try {
        MetricsManager.get().init();
        // start a transaction
        GlobalBeginRequest request = new GlobalBeginRequest();
        request.setTransactionName("test_transaction");
        GlobalBeginResponse response = new GlobalBeginResponse();
        coordinator.doGlobalBegin(request, response, new RpcContext());
        Map<String, Measurement> measurements = new HashMap<>();
        MetricsManager.get().getRegistry().measure().forEach(measurement -> measurements.put(measurement.getId().toString(), measurement));
        Assertions.assertEquals(1, measurements.size());
        Assertions.assertEquals(1, measurements.get("seata.transaction(applicationId=null,group=null,meter=counter,role=tc,status=active)").getValue(), 0);
        // commit this transaction
        GlobalCommitRequest commitRequest = new GlobalCommitRequest();
        commitRequest.setXid(response.getXid());
        coordinator.doGlobalCommit(commitRequest, new GlobalCommitResponse(), new RpcContext());
        // we need sleep for a short while because default canBeCommittedAsync() is true
        Thread.sleep(200);
        measurements.clear();
        MetricsManager.get().getRegistry().measure().forEach(measurement -> measurements.put(measurement.getId().toString(), measurement));
        Assertions.assertEquals(9, measurements.size());
        Assertions.assertEquals(0, measurements.get("seata.transaction(applicationId=null,group=null,meter=counter,role=tc,status=active)").getValue(), 0);
        Assertions.assertEquals(1, measurements.get("seata.transaction(applicationId=null,group=null,meter=counter,role=tc,status=committed)").getValue(), 0);
        Assertions.assertEquals(1, measurements.get("seata.transaction(applicationId=null,group=null,meter=summary,role=tc,statistic=count,status=committed)").getValue(), 0);
        Assertions.assertEquals(1, measurements.get("seata.transaction(applicationId=null,group=null,meter=summary,role=tc,statistic=total,status=committed)").getValue(), 0);
        Assertions.assertEquals(1, measurements.get("seata.transaction(applicationId=null,group=null,meter=timer,role=tc,statistic=count,status=committed)").getValue(), 0);
        // start another new transaction
        request = new GlobalBeginRequest();
        request.setTransactionName("test_transaction_2");
        response = new GlobalBeginResponse();
        coordinator.doGlobalBegin(request, response, new RpcContext());
        // rollback this transaction
        GlobalRollbackRequest rollbackRequest = new GlobalRollbackRequest();
        rollbackRequest.setXid(response.getXid());
        coordinator.doGlobalRollback(rollbackRequest, new GlobalRollbackResponse(), new RpcContext());
        Thread.sleep(200);
        measurements.clear();
        MetricsManager.get().getRegistry().measure().forEach(measurement -> measurements.put(measurement.getId().toString(), measurement));
        Assertions.assertEquals(17, measurements.size());
        Assertions.assertEquals(0, measurements.get("seata.transaction(applicationId=null,group=null,meter=counter,role=tc,status=active)").getValue(), 0);
        Assertions.assertEquals(1, measurements.get("seata.transaction(applicationId=null,group=null,meter=counter,role=tc,status=committed)").getValue(), 0);
        Assertions.assertEquals(0, measurements.get("seata.transaction(applicationId=null,group=null,meter=summary,role=tc,statistic=count,status=committed)").getValue(), 0);
        Assertions.assertEquals(0, measurements.get("seata.transaction(applicationId=null,group=null,meter=summary,role=tc,statistic=total,status=committed)").getValue(), 0);
        Assertions.assertEquals(0, measurements.get("seata.transaction(applicationId=null,group=null,meter=timer,role=tc,statistic=count,status=committed)").getValue(), 0);
        Assertions.assertEquals(1, measurements.get("seata.transaction(applicationId=null,group=null,meter=counter,role=tc,status=rollbacked)").getValue(), 0);
        Assertions.assertEquals(1, measurements.get("seata.transaction(applicationId=null,group=null,meter=summary,role=tc,statistic=count,status=rollbacked)").getValue(), 0);
        Assertions.assertEquals(1, measurements.get("seata.transaction(applicationId=null,group=null,meter=summary,role=tc,statistic=total,status=rollbacked)").getValue(), 0);
        Assertions.assertEquals(1, measurements.get("seata.transaction(applicationId=null,group=null,meter=timer,role=tc,statistic=count,status=rollbacked)").getValue(), 0);
    } finally {
        coordinator.destroy();
        SessionHolder.destroy();
    }
}
Also used : MockServerMessageSender(io.seata.server.coordinator.DefaultCoordinatorTest.MockServerMessageSender) Measurement(io.seata.metrics.Measurement) GlobalCommitRequest(io.seata.core.protocol.transaction.GlobalCommitRequest) HashMap(java.util.HashMap) GlobalCommitResponse(io.seata.core.protocol.transaction.GlobalCommitResponse) GlobalRollbackResponse(io.seata.core.protocol.transaction.GlobalRollbackResponse) RpcContext(io.seata.core.rpc.RpcContext) GlobalRollbackRequest(io.seata.core.protocol.transaction.GlobalRollbackRequest) GlobalBeginRequest(io.seata.core.protocol.transaction.GlobalBeginRequest) GlobalBeginResponse(io.seata.core.protocol.transaction.GlobalBeginResponse) Test(org.junit.jupiter.api.Test)

Example 4 with RpcContext

use of io.seata.core.rpc.RpcContext in project seata by seata.

the class ChannelManager method registerRMChannel.

/**
 * Register rm channel.
 *
 * @param resourceManagerRequest the resource manager request
 * @param channel                the channel
 * @throws IncompatibleVersionException the incompatible  version exception
 */
public static void registerRMChannel(RegisterRMRequest resourceManagerRequest, Channel channel) throws IncompatibleVersionException {
    Version.checkVersion(resourceManagerRequest.getVersion());
    Set<String> dbkeySet = dbKeytoSet(resourceManagerRequest.getResourceIds());
    RpcContext rpcContext;
    if (!IDENTIFIED_CHANNELS.containsKey(channel)) {
        rpcContext = buildChannelHolder(NettyPoolKey.TransactionRole.RMROLE, resourceManagerRequest.getVersion(), resourceManagerRequest.getApplicationId(), resourceManagerRequest.getTransactionServiceGroup(), resourceManagerRequest.getResourceIds(), channel);
        rpcContext.holdInIdentifiedChannels(IDENTIFIED_CHANNELS);
    } else {
        rpcContext = IDENTIFIED_CHANNELS.get(channel);
        rpcContext.addResources(dbkeySet);
    }
    if (dbkeySet == null || dbkeySet.isEmpty()) {
        return;
    }
    for (String resourceId : dbkeySet) {
        String clientIp;
        ConcurrentMap<Integer, RpcContext> portMap = CollectionUtils.computeIfAbsent(RM_CHANNELS, resourceId, key -> new ConcurrentHashMap<>()).computeIfAbsent(resourceManagerRequest.getApplicationId(), key -> new ConcurrentHashMap<>()).computeIfAbsent(clientIp = ChannelUtil.getClientIpFromChannel(channel), key -> new ConcurrentHashMap<>());
        rpcContext.holdInResourceManagerChannels(resourceId, portMap);
        updateChannelsResource(resourceId, clientIp, resourceManagerRequest.getApplicationId());
    }
}
Also used : RpcContext(io.seata.core.rpc.RpcContext) Arrays(java.util.Arrays) Logger(org.slf4j.Logger) RpcContext(io.seata.core.rpc.RpcContext) CollectionUtils(io.seata.common.util.CollectionUtils) LoggerFactory(org.slf4j.LoggerFactory) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) HashMap(java.util.HashMap) Constants(io.seata.common.Constants) ConcurrentMap(java.util.concurrent.ConcurrentMap) Channel(io.netty.channel.Channel) RegisterRMRequest(io.seata.core.protocol.RegisterRMRequest) HashSet(java.util.HashSet) Map(java.util.Map) RegisterTMRequest(io.seata.core.protocol.RegisterTMRequest) FrameworkException(io.seata.common.exception.FrameworkException) StringUtils(io.seata.common.util.StringUtils) Version(io.seata.core.protocol.Version) IncompatibleVersionException(io.seata.core.protocol.IncompatibleVersionException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 5 with RpcContext

use of io.seata.core.rpc.RpcContext in project seata by seata.

the class ChannelManager method registerTMChannel.

/**
 * Register tm channel.
 *
 * @param request the request
 * @param channel the channel
 * @throws IncompatibleVersionException the incompatible version exception
 */
public static void registerTMChannel(RegisterTMRequest request, Channel channel) throws IncompatibleVersionException {
    Version.checkVersion(request.getVersion());
    RpcContext rpcContext = buildChannelHolder(NettyPoolKey.TransactionRole.TMROLE, request.getVersion(), request.getApplicationId(), request.getTransactionServiceGroup(), null, channel);
    rpcContext.holdInIdentifiedChannels(IDENTIFIED_CHANNELS);
    String clientIdentified = rpcContext.getApplicationId() + Constants.CLIENT_ID_SPLIT_CHAR + ChannelUtil.getClientIpFromChannel(channel);
    ConcurrentMap<Integer, RpcContext> clientIdentifiedMap = CollectionUtils.computeIfAbsent(TM_CHANNELS, clientIdentified, key -> new ConcurrentHashMap<>());
    rpcContext.holdInClientChannels(clientIdentifiedMap);
}
Also used : RpcContext(io.seata.core.rpc.RpcContext)

Aggregations

RpcContext (io.seata.core.rpc.RpcContext)10 ConcurrentMap (java.util.concurrent.ConcurrentMap)5 Channel (io.netty.channel.Channel)4 HashMap (java.util.HashMap)3 FrameworkException (io.seata.common.exception.FrameworkException)2 AbstractResultMessage (io.seata.core.protocol.AbstractResultMessage)2 Map (java.util.Map)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 Constants (io.seata.common.Constants)1 CollectionUtils (io.seata.common.util.CollectionUtils)1 StringUtils (io.seata.common.util.StringUtils)1 AbstractMessage (io.seata.core.protocol.AbstractMessage)1 IncompatibleVersionException (io.seata.core.protocol.IncompatibleVersionException)1 MergeResultMessage (io.seata.core.protocol.MergeResultMessage)1 MergedWarpMessage (io.seata.core.protocol.MergedWarpMessage)1 RegisterRMRequest (io.seata.core.protocol.RegisterRMRequest)1 RegisterTMRequest (io.seata.core.protocol.RegisterTMRequest)1 Version (io.seata.core.protocol.Version)1 GlobalBeginRequest (io.seata.core.protocol.transaction.GlobalBeginRequest)1 GlobalBeginResponse (io.seata.core.protocol.transaction.GlobalBeginResponse)1