Search in sources :

Example 1 with Events

use of com.alibaba.otter.canal.store.model.Events in project canal by alibaba.

the class MemoryEventStoreWithBuffer method doGet.

private Events<Event> doGet(Position start, int batchSize) throws CanalStoreException {
    LogPosition startPosition = (LogPosition) start;
    long current = getSequence.get();
    long maxAbleSequence = putSequence.get();
    long next = current;
    long end = current;
    // 如果startPosition为null,说明是第一次,默认+1处理
    if (startPosition == null || !startPosition.getPostion().isIncluded()) {
        // 第一次订阅之后,需要包含一下start位置,防止丢失第一条记录
        next = next + 1;
    }
    if (current >= maxAbleSequence) {
        return new Events<Event>();
    }
    Events<Event> result = new Events<Event>();
    List<Event> entrys = result.getEvents();
    long memsize = 0;
    if (batchMode.isItemSize()) {
        end = (next + batchSize - 1) < maxAbleSequence ? (next + batchSize - 1) : maxAbleSequence;
        // 提取数据并返回
        for (; next <= end; next++) {
            Event event = entries[getIndex(next)];
            if (ddlIsolation && isDdl(event.getEntry().getHeader().getEventType())) {
                // 如果是ddl隔离,直接返回
                if (entrys.size() == 0) {
                    // 如果没有DML事件,加入当前的DDL事件
                    entrys.add(event);
                    // 更新end为当前
                    end = next;
                } else {
                    // 如果之前已经有DML事件,直接返回了,因为不包含当前next这记录,需要回退一个位置
                    // next-1一定大于current,不需要判断
                    end = next - 1;
                }
                break;
            } else {
                entrys.add(event);
            }
        }
    } else {
        long maxMemSize = batchSize * bufferMemUnit;
        for (; memsize <= maxMemSize && next <= maxAbleSequence; next++) {
            // 永远保证可以取出第一条的记录,避免死锁
            Event event = entries[getIndex(next)];
            if (ddlIsolation && isDdl(event.getEntry().getHeader().getEventType())) {
                // 如果是ddl隔离,直接返回
                if (entrys.size() == 0) {
                    // 如果没有DML事件,加入当前的DDL事件
                    entrys.add(event);
                    // 更新end为当前
                    end = next;
                } else {
                    // 如果之前已经有DML事件,直接返回了,因为不包含当前next这记录,需要回退一个位置
                    // next-1一定大于current,不需要判断
                    end = next - 1;
                }
                break;
            } else {
                entrys.add(event);
                memsize += calculateSize(event);
                // 记录end位点
                end = next;
            }
        }
    }
    PositionRange<LogPosition> range = new PositionRange<LogPosition>();
    result.setPositionRange(range);
    range.setStart(CanalEventUtils.createPosition(entrys.get(0)));
    range.setEnd(CanalEventUtils.createPosition(entrys.get(result.getEvents().size() - 1)));
    for (int i = entrys.size() - 1; i >= 0; i--) {
        Event event = entrys.get(i);
        if (CanalEntry.EntryType.TRANSACTIONBEGIN == event.getEntry().getEntryType() || CanalEntry.EntryType.TRANSACTIONEND == event.getEntry().getEntryType() || isDdl(event.getEntry().getHeader().getEventType())) {
            // 将事务头/尾设置可被为ack的点
            range.setAck(CanalEventUtils.createPosition(event));
            break;
        }
    }
    if (getSequence.compareAndSet(current, end)) {
        getMemSize.addAndGet(memsize);
        notFull.signal();
        return result;
    } else {
        return new Events<Event>();
    }
}
Also used : Events(com.alibaba.otter.canal.store.model.Events) PositionRange(com.alibaba.otter.canal.protocol.position.PositionRange) Event(com.alibaba.otter.canal.store.model.Event) LogPosition(com.alibaba.otter.canal.protocol.position.LogPosition)

Aggregations

LogPosition (com.alibaba.otter.canal.protocol.position.LogPosition)1 PositionRange (com.alibaba.otter.canal.protocol.position.PositionRange)1 Event (com.alibaba.otter.canal.store.model.Event)1 Events (com.alibaba.otter.canal.store.model.Events)1