ChannelProcessor类主要的作用是处理从Source拿过来的event。
这个最主要的是两个成员变量和两个方法。
private final ChannelSelector selector; private final InterceptorChain interceptorChain;
两个方法的代码差不多,一个是批量的一个是单个的,我们分析一下批量的方法。
先看一下代码:
public void processEventBatch(List<Event> events) { Preconditions.checkNotNull(events, "Event list must not be null"); events = interceptorChain.intercept(events); Map<Channel, List<Event>> reqChannelQueue = new LinkedHashMap<Channel, List<Event>>(); Map<Channel, List<Event>> optChannelQueue = new LinkedHashMap<Channel, List<Event>>(); for (Event event : events) { List<Channel> reqChannels = selector.getRequiredChannels(event); for (Channel ch : reqChannels) { List<Event> eventQueue = reqChannelQueue.get(ch); if (eventQueue == null) { eventQueue = new ArrayList<Event>(); reqChannelQueue.put(ch, eventQueue); } eventQueue.add(event); } List<Channel> optChannels = selector.getOptionalChannels(event); for (Channel ch : optChannels) { List<Event> eventQueue = optChannelQueue.get(ch); if (eventQueue == null) { eventQueue = new ArrayList<Event>(); optChannelQueue.put(ch, eventQueue); } eventQueue.add(event); } } // Process required channels for (Channel reqChannel : reqChannelQueue.keySet()) { Transaction tx = reqChannel.getTransaction(); Preconditions.checkNotNull(tx, "Transaction object must not be null"); try { tx.begin(); List<Event> batch = reqChannelQueue.get(reqChannel); for (Event event : batch) { reqChannel.put(event); } tx.commit(); } catch (Throwable t) { tx.rollback(); if (t instanceof Error) { LOG.error("Error while writing to required channel: " + reqChannel, t); throw (Error) t; } else if (t instanceof ChannelException) { throw (ChannelException) t; } else { throw new ChannelException("Unable to put batch on required " + "channel: " + reqChannel, t); } } finally { if (tx != null) { tx.close(); } } } // Process optional channels for (Channel optChannel : optChannelQueue.keySet()) { Transaction tx = optChannel.getTransaction(); Preconditions.checkNotNull(tx, "Transaction object must not be null"); try { tx.begin(); List<Event> batch = optChannelQueue.get(optChannel); for (Event event : batch) { optChannel.put(event); } tx.commit(); } catch (Throwable t) { tx.rollback(); LOG.error("Unable to put batch on optional channel: " + optChannel, t); if (t instanceof Error) { throw (Error) t; } } finally { if (tx != null) { tx.close(); } } } }
1.首先events会在interceptorChain中intercept处理,比如在头部加时间戳等
2.新建了两个channelQueue的map,这两个map一个是必须的channel,另一个是可选的channel,map的类型是linkedHashMap,说明是有序的。
3.遍历events,根据selector和event确定event要发送到哪些channel
4.遍历reqChannels,把event放到对应的channel的eventlist中
5.遍历optChannels,把event放到对应的channel的eventlist中
6.遍历reqMap的key,获取channel中transaction对象,开启事务,把map中channel对应的events放到channel中,都放进去后,会提交事务。如果有错误的话,事务会进行回滚。最后,会关闭事务。
7.和上面相同方式处理optMap