com.github.brandtg.switchboard.MysqlLogPuller Maven / Gradle / Ivy
The newest version!
/**
* Copyright (C) 2015 Greg Brandt ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.brandtg.switchboard;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
public abstract class MysqlLogPuller {
private static final String ENCODING = "UTF-8";
private static final Logger LOG = LoggerFactory.getLogger(MysqlLogPuller.class);
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
protected final String database;
protected final long lastIndex;
protected final InetSocketAddress sourceAddress;
protected final InetSocketAddress sinkAddress;
protected final PipedInputStream inputStream;
protected final PipedOutputStream outputStream;
protected final AtomicBoolean isStarted;
protected EventLoopGroup eventExecutors;
protected ExecutorService callbackExecutor;
protected ExecutorService refreshExecutor;
protected LogReceiver logReceiver;
protected LogPuller logPuller;
public MysqlLogPuller(String database,
InetSocketAddress sourceAddress,
InetSocketAddress sinkAddress) {
this(database, sourceAddress, sinkAddress, -1);
}
/**
* Creates an agent to listen to MySQL changes (via binlog).
*
* @param database
* The MySQL database name
* @param sourceAddress
* The switchboard server address from which to pull events
* @param sinkAddress
* The local listener port to receive raw binlog data
* @param lastIndex
* The last index that was processed by whoever is constructing this (if -1, processed none)
*/
public MysqlLogPuller(String database,
InetSocketAddress sourceAddress,
InetSocketAddress sinkAddress,
long lastIndex) {
this.database = database;
this.lastIndex = lastIndex;
this.sourceAddress = sourceAddress;
this.sinkAddress = sinkAddress;
this.inputStream = new PipedInputStream();
this.outputStream = new PipedOutputStream();
this.isStarted = new AtomicBoolean();
}
protected abstract Runnable getCallback();
/**
* Starts pulling events from switchboard server.
*/
public void start() throws Exception {
if (!isStarted.getAndSet(true)) {
outputStream.connect(inputStream);
callbackExecutor = Executors.newSingleThreadExecutor();
refreshExecutor = Executors.newSingleThreadExecutor();
eventExecutors = new NioEventLoopGroup();
// Start server to receive log segments
logReceiver = new LogReceiver(sinkAddress, eventExecutors, outputStream);
logReceiver.start();
// Iterates through events and fires appropriate callbacks
callbackExecutor.submit(getCallback());
// Pulls log indexes
logPuller = new LogPuller(sourceAddress, sinkAddress, database, lastIndex);
logReceiver.registerListener(logPuller);
refreshExecutor.submit(logPuller);
}
}
/**
* Stops pulling events from switchboard server.
*/
public void shutdown() throws Exception {
if (isStarted.getAndSet(false)) {
logPuller.shutdown();
try {
logReceiver.shutdown();
} catch (Exception e) {
LOG.error("Exception while shutting down log receiver", e);
}
eventExecutors.shutdownGracefully();
callbackExecutor.shutdown();
refreshExecutor.shutdown();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy