GOSSIP-85 Factor out PassiveGossipThread
This commit is contained in:
@ -241,4 +241,5 @@ public class GossipSettings {
|
|||||||
public void setProtocolManagerClass(String protocolManagerClass) {
|
public void setProtocolManagerClass(String protocolManagerClass) {
|
||||||
this.protocolManagerClass = protocolManagerClass;
|
this.protocolManagerClass = protocolManagerClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,9 @@ public abstract class GossipManager {
|
|||||||
public static final Logger LOGGER = Logger.getLogger(GossipManager.class);
|
public static final Logger LOGGER = Logger.getLogger(GossipManager.class);
|
||||||
|
|
||||||
// this mapper is used for ring and user-data persistence only. NOT messages.
|
// this mapper is used for ring and user-data persistence only. NOT messages.
|
||||||
public static final ObjectMapper metdataObjectMapper = new ObjectMapper() {{
|
public static final ObjectMapper metdataObjectMapper = new ObjectMapper() {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
{
|
||||||
enableDefaultTyping();
|
enableDefaultTyping();
|
||||||
configure(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS, false);
|
configure(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS, false);
|
||||||
}};
|
}};
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 org.apache.gossip.manager;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
|
|
||||||
import org.apache.gossip.model.Base;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class handles the passive cycle,
|
|
||||||
* where this client has received an incoming message.
|
|
||||||
*/
|
|
||||||
public class PassiveGossipThread implements Runnable {
|
|
||||||
|
|
||||||
public static final Logger LOGGER = Logger.getLogger(PassiveGossipThread.class);
|
|
||||||
|
|
||||||
|
|
||||||
private final AtomicBoolean keepRunning;
|
|
||||||
private final GossipCore gossipCore;
|
|
||||||
private final GossipManager gossipManager;
|
|
||||||
|
|
||||||
public PassiveGossipThread(GossipManager gossipManager, GossipCore gossipCore) {
|
|
||||||
this.gossipManager = gossipManager;
|
|
||||||
this.gossipCore = gossipCore;
|
|
||||||
if (gossipManager.getMyself().getClusterName() == null){
|
|
||||||
throw new IllegalArgumentException("Cluster was null");
|
|
||||||
}
|
|
||||||
|
|
||||||
keepRunning = new AtomicBoolean(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
while (keepRunning.get()) {
|
|
||||||
try {
|
|
||||||
byte[] buf = gossipManager.getTransportManager().read();
|
|
||||||
try {
|
|
||||||
Base message = gossipManager.getProtocolManager().read(buf);
|
|
||||||
gossipCore.receive(message);
|
|
||||||
gossipManager.getMemberStateRefresher().run();
|
|
||||||
} catch (RuntimeException ex) {//TODO trap json exception
|
|
||||||
LOGGER.error("Unable to process message", ex);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
// InterruptedException are completely normal here because of the blocking lifecycle.
|
|
||||||
if (!(e.getCause() instanceof InterruptedException)) {
|
|
||||||
LOGGER.error(e);
|
|
||||||
}
|
|
||||||
keepRunning.set(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void requestStop() {
|
|
||||||
keepRunning.set(false);
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,14 +22,11 @@ import java.io.FileInputStream;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.NavigableSet;
|
import java.util.NavigableSet;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonGenerator;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.apache.gossip.LocalMember;
|
import org.apache.gossip.LocalMember;
|
||||||
import org.apache.gossip.crdt.CrdtModule;
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
public class RingStatePersister implements Runnable {
|
public class RingStatePersister implements Runnable {
|
||||||
|
@ -21,7 +21,6 @@ import com.codahale.metrics.MetricRegistry;
|
|||||||
import org.apache.gossip.manager.AbstractActiveGossiper;
|
import org.apache.gossip.manager.AbstractActiveGossiper;
|
||||||
import org.apache.gossip.manager.GossipCore;
|
import org.apache.gossip.manager.GossipCore;
|
||||||
import org.apache.gossip.manager.GossipManager;
|
import org.apache.gossip.manager.GossipManager;
|
||||||
import org.apache.gossip.manager.PassiveGossipThread;
|
|
||||||
import org.apache.gossip.utils.ReflectionUtils;
|
import org.apache.gossip.utils.ReflectionUtils;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
@ -36,14 +35,14 @@ public abstract class AbstractTransportManager implements TransportManager {
|
|||||||
|
|
||||||
public static final Logger LOGGER = Logger.getLogger(AbstractTransportManager.class);
|
public static final Logger LOGGER = Logger.getLogger(AbstractTransportManager.class);
|
||||||
|
|
||||||
private final PassiveGossipThread passiveGossipThread;
|
|
||||||
private final ExecutorService gossipThreadExecutor;
|
private final ExecutorService gossipThreadExecutor;
|
||||||
|
|
||||||
private final AbstractActiveGossiper activeGossipThread;
|
private final AbstractActiveGossiper activeGossipThread;
|
||||||
|
protected final GossipManager gossipManager;
|
||||||
|
protected final GossipCore gossipCore;
|
||||||
|
|
||||||
public AbstractTransportManager(GossipManager gossipManager, GossipCore gossipCore) {
|
public AbstractTransportManager(GossipManager gossipManager, GossipCore gossipCore) {
|
||||||
|
this.gossipManager = gossipManager;
|
||||||
passiveGossipThread = new PassiveGossipThread(gossipManager, gossipCore);
|
this.gossipCore = gossipCore;
|
||||||
gossipThreadExecutor = Executors.newCachedThreadPool();
|
gossipThreadExecutor = Executors.newCachedThreadPool();
|
||||||
activeGossipThread = ReflectionUtils.constructWithReflection(
|
activeGossipThread = ReflectionUtils.constructWithReflection(
|
||||||
gossipManager.getSettings().getActiveGossipClass(),
|
gossipManager.getSettings().getActiveGossipClass(),
|
||||||
@ -58,7 +57,6 @@ public abstract class AbstractTransportManager implements TransportManager {
|
|||||||
// shut down threads etc.
|
// shut down threads etc.
|
||||||
@Override
|
@Override
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
passiveGossipThread.requestStop();
|
|
||||||
gossipThreadExecutor.shutdown();
|
gossipThreadExecutor.shutdown();
|
||||||
if (activeGossipThread != null) {
|
if (activeGossipThread != null) {
|
||||||
activeGossipThread.shutdown();
|
activeGossipThread.shutdown();
|
||||||
@ -81,7 +79,5 @@ public abstract class AbstractTransportManager implements TransportManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startEndpoint() {
|
public abstract void startEndpoint();
|
||||||
gossipThreadExecutor.execute(passiveGossipThread);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ public class MessageHandlerTest {
|
|||||||
|
|
||||||
@Test(expected = NullPointerException.class)
|
@Test(expected = NullPointerException.class)
|
||||||
public void cantAddNullHandler2() {
|
public void cantAddNullHandler2() {
|
||||||
MessageHandler handler = MessageHandlerFactory.concurrentHandler(
|
MessageHandlerFactory.concurrentHandler(
|
||||||
new TypedMessageHandler(FakeMessage.class, new FakeMessageHandler()),
|
new TypedMessageHandler(FakeMessage.class, new FakeMessageHandler()),
|
||||||
null,
|
null,
|
||||||
new TypedMessageHandler(FakeMessage.class, new FakeMessageHandler())
|
new TypedMessageHandler(FakeMessage.class, new FakeMessageHandler())
|
||||||
|
@ -71,6 +71,5 @@ public class UnitTestTransportManager extends AbstractTransportManager {
|
|||||||
@Override
|
@Override
|
||||||
public void startEndpoint() {
|
public void startEndpoint() {
|
||||||
allManagers.put(localEndpoint, this);
|
allManagers.put(localEndpoint, this);
|
||||||
super.startEndpoint();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
88
gossip-itest/pom.xml
Normal file
88
gossip-itest/pom.xml
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You 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.
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.apache.gossip</groupId>
|
||||||
|
<artifactId>gossip-parent</artifactId>
|
||||||
|
<version>0.1.3-incubating-SNAPSHOT</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<name>Gossip itest</name>
|
||||||
|
<artifactId>gossip-itest</artifactId>
|
||||||
|
<version>0.1.3-incubating-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.gossip</groupId>
|
||||||
|
<artifactId>gossip-base</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.gossip</groupId>
|
||||||
|
<artifactId>gossip-base</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>test-jar</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.gossip</groupId>
|
||||||
|
<artifactId>gossip-protocol-jackson</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.gossip</groupId>
|
||||||
|
<artifactId>gossip-transport-udp</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>${java.version}</source>
|
||||||
|
<target>${java.version}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.19.1</version>
|
||||||
|
<configuration>
|
||||||
|
<systemPropertyVariables>
|
||||||
|
<java.io.tmpdir>${project.build.directory}</java.io.tmpdir>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
</configuration>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.platform</groupId>
|
||||||
|
<artifactId>junit-platform-surefire-provider</artifactId>
|
||||||
|
<version>${junit.platform.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -47,8 +47,6 @@ public class DataTest extends AbstractIntegrationBase {
|
|||||||
GossipSettings settings = new GossipSettings();
|
GossipSettings settings = new GossipSettings();
|
||||||
settings.setPersistRingState(false);
|
settings.setPersistRingState(false);
|
||||||
settings.setPersistDataState(false);
|
settings.setPersistDataState(false);
|
||||||
settings.setTransportManagerClass("org.apache.gossip.transport.UnitTestTransportManager");
|
|
||||||
settings.setProtocolManagerClass("org.apache.gossip.protocol.UnitTestProtocolManager");
|
|
||||||
String cluster = UUID.randomUUID().toString();
|
String cluster = UUID.randomUUID().toString();
|
||||||
int seedNodes = 1;
|
int seedNodes = 1;
|
||||||
List<Member> startupMembers = new ArrayList<>();
|
List<Member> startupMembers = new ArrayList<>();
|
@ -43,8 +43,6 @@ public class IdAndPropertyTest extends AbstractIntegrationBase {
|
|||||||
public void testDatacenterRackGossiper() throws URISyntaxException, UnknownHostException, InterruptedException {
|
public void testDatacenterRackGossiper() throws URISyntaxException, UnknownHostException, InterruptedException {
|
||||||
GossipSettings settings = new GossipSettings();
|
GossipSettings settings = new GossipSettings();
|
||||||
settings.setActiveGossipClass(DatacenterRackAwareActiveGossiper.class.getName());
|
settings.setActiveGossipClass(DatacenterRackAwareActiveGossiper.class.getName());
|
||||||
settings.setTransportManagerClass("org.apache.gossip.transport.UnitTestTransportManager");
|
|
||||||
settings.setProtocolManagerClass("org.apache.gossip.protocol.UnitTestProtocolManager");
|
|
||||||
List<Member> startupMembers = new ArrayList<>();
|
List<Member> startupMembers = new ArrayList<>();
|
||||||
Map<String, String> x = new HashMap<>();
|
Map<String, String> x = new HashMap<>();
|
||||||
x.put("a", "b");
|
x.put("a", "b");
|
@ -50,8 +50,6 @@ public class ShutdownDeadtimeTest {
|
|||||||
public void DeadNodesDoNotComeAliveAgain()
|
public void DeadNodesDoNotComeAliveAgain()
|
||||||
throws InterruptedException, UnknownHostException, URISyntaxException {
|
throws InterruptedException, UnknownHostException, URISyntaxException {
|
||||||
GossipSettings settings = new GossipSettings(100, 10000, 1000, 1, 10.0, "normal");
|
GossipSettings settings = new GossipSettings(100, 10000, 1000, 1, 10.0, "normal");
|
||||||
settings.setTransportManagerClass("org.apache.gossip.transport.UnitTestTransportManager");
|
|
||||||
settings.setProtocolManagerClass("org.apache.gossip.protocol.UnitTestProtocolManager");
|
|
||||||
settings.setPersistRingState(false);
|
settings.setPersistRingState(false);
|
||||||
settings.setPersistDataState(false);
|
settings.setPersistDataState(false);
|
||||||
String cluster = UUID.randomUUID().toString();
|
String cluster = UUID.randomUUID().toString();
|
@ -45,8 +45,6 @@ public class SignedMessageTest extends AbstractIntegrationBase {
|
|||||||
settings.setPersistRingState(false);
|
settings.setPersistRingState(false);
|
||||||
settings.setPersistDataState(false);
|
settings.setPersistDataState(false);
|
||||||
settings.setSignMessages(true);
|
settings.setSignMessages(true);
|
||||||
settings.setTransportManagerClass("org.apache.gossip.transport.UnitTestTransportManager");
|
|
||||||
settings.setProtocolManagerClass("org.apache.gossip.protocol.UnitTestProtocolManager");
|
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
@ -50,8 +50,6 @@ public class TenNodeThreeSeedTest {
|
|||||||
GossipSettings settings = new GossipSettings(1000, 10000, 1000, 1, 1.6, "exponential");
|
GossipSettings settings = new GossipSettings(1000, 10000, 1000, 1, 1.6, "exponential");
|
||||||
settings.setPersistRingState(false);
|
settings.setPersistRingState(false);
|
||||||
settings.setPersistDataState(false);
|
settings.setPersistDataState(false);
|
||||||
settings.setTransportManagerClass("org.apache.gossip.transport.UnitTestTransportManager");
|
|
||||||
settings.setProtocolManagerClass("org.apache.gossip.protocol.UnitTestProtocolManager");
|
|
||||||
String cluster = UUID.randomUUID().toString();
|
String cluster = UUID.randomUUID().toString();
|
||||||
int seedNodes = 3;
|
int seedNodes = 3;
|
||||||
List<Member> startupMembers = new ArrayList<>();
|
List<Member> startupMembers = new ArrayList<>();
|
@ -36,12 +36,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.gossip</groupId>
|
<groupId>org.apache.gossip</groupId>
|
||||||
<artifactId>gossip-base</artifactId>
|
<artifactId>gossip-base</artifactId>
|
||||||
<version>0.1.3-incubating-SNAPSHOT</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.gossip</groupId>
|
<groupId>org.apache.gossip</groupId>
|
||||||
<artifactId>gossip-base</artifactId>
|
<artifactId>gossip-base</artifactId>
|
||||||
<version>0.1.3-incubating-SNAPSHOT</version>
|
<version>${project.version}</version>
|
||||||
<type>test-jar</type>
|
<type>test-jar</type>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@ -25,9 +25,7 @@ import org.apache.gossip.Member;
|
|||||||
import org.apache.gossip.crdt.OrSet;
|
import org.apache.gossip.crdt.OrSet;
|
||||||
import org.apache.gossip.manager.GossipManager;
|
import org.apache.gossip.manager.GossipManager;
|
||||||
import org.apache.gossip.manager.GossipManagerBuilder;
|
import org.apache.gossip.manager.GossipManagerBuilder;
|
||||||
import org.apache.gossip.model.Base;
|
|
||||||
import org.apache.gossip.protocol.ProtocolManager;
|
import org.apache.gossip.protocol.ProtocolManager;
|
||||||
import org.apache.gossip.udp.Trackable;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -36,11 +34,7 @@ import java.net.URI;
|
|||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class JacksonTest {
|
public class JacksonTest {
|
||||||
|
@ -41,6 +41,7 @@ class TestMessage extends Base implements Trackable {
|
|||||||
private Object[] arrayOfThings;
|
private Object[] arrayOfThings;
|
||||||
private Map<String, String> mapOfThings = new HashMap<>();
|
private Map<String, String> mapOfThings = new HashMap<>();
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")//Used by ObjectMapper
|
||||||
private TestMessage() {
|
private TestMessage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.gossip</groupId>
|
<groupId>org.apache.gossip</groupId>
|
||||||
<artifactId>gossip-base</artifactId>
|
<artifactId>gossip-base</artifactId>
|
||||||
<version>0.1.3-incubating-SNAPSHOT</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ package org.apache.gossip.transport.udp;
|
|||||||
|
|
||||||
import org.apache.gossip.manager.GossipCore;
|
import org.apache.gossip.manager.GossipCore;
|
||||||
import org.apache.gossip.manager.GossipManager;
|
import org.apache.gossip.manager.GossipManager;
|
||||||
|
import org.apache.gossip.model.Base;
|
||||||
import org.apache.gossip.transport.AbstractTransportManager;
|
import org.apache.gossip.transport.AbstractTransportManager;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
@ -30,12 +31,13 @@ import java.net.InetSocketAddress;
|
|||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is constructed by reflection in GossipManager.
|
* This class is constructed by reflection in GossipManager.
|
||||||
* It manages transport (byte read/write) operations over UDP.
|
* It manages transport (byte read/write) operations over UDP.
|
||||||
*/
|
*/
|
||||||
public class UdpTransportManager extends AbstractTransportManager {
|
public class UdpTransportManager extends AbstractTransportManager implements Runnable {
|
||||||
|
|
||||||
public static final Logger LOGGER = Logger.getLogger(UdpTransportManager.class);
|
public static final Logger LOGGER = Logger.getLogger(UdpTransportManager.class);
|
||||||
|
|
||||||
@ -44,12 +46,14 @@ public class UdpTransportManager extends AbstractTransportManager {
|
|||||||
|
|
||||||
private final int soTimeout;
|
private final int soTimeout;
|
||||||
|
|
||||||
|
private final Thread me;
|
||||||
|
|
||||||
|
private final AtomicBoolean keepRunning = new AtomicBoolean(true);
|
||||||
|
|
||||||
/** required for reflection to work! */
|
/** required for reflection to work! */
|
||||||
public UdpTransportManager(GossipManager gossipManager, GossipCore gossipCore) {
|
public UdpTransportManager(GossipManager gossipManager, GossipCore gossipCore) {
|
||||||
super(gossipManager, gossipCore);
|
super(gossipManager, gossipCore);
|
||||||
|
|
||||||
soTimeout = gossipManager.getSettings().getGossipInterval() * 2;
|
soTimeout = gossipManager.getSettings().getGossipInterval() * 2;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SocketAddress socketAddress = new InetSocketAddress(gossipManager.getMyself().getUri().getHost(),
|
SocketAddress socketAddress = new InetSocketAddress(gossipManager.getMyself().getUri().getHost(),
|
||||||
gossipManager.getMyself().getUri().getPort());
|
gossipManager.getMyself().getUri().getPort());
|
||||||
@ -58,12 +62,38 @@ public class UdpTransportManager extends AbstractTransportManager {
|
|||||||
LOGGER.warn(ex);
|
LOGGER.warn(ex);
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
|
me = new Thread(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (keepRunning.get()) {
|
||||||
|
try {
|
||||||
|
byte[] buf = read();
|
||||||
|
try {
|
||||||
|
Base message = gossipManager.getProtocolManager().read(buf);
|
||||||
|
gossipCore.receive(message);
|
||||||
|
//TODO this is suspect
|
||||||
|
gossipManager.getMemberStateRefresher().run();
|
||||||
|
} catch (RuntimeException ex) {//TODO trap json exception
|
||||||
|
LOGGER.error("Unable to process message", ex);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
// InterruptedException are completely normal here because of the blocking lifecycle.
|
||||||
|
if (!(e.getCause() instanceof InterruptedException)) {
|
||||||
|
LOGGER.error(e);
|
||||||
|
}
|
||||||
|
keepRunning.set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
|
keepRunning.set(false);
|
||||||
server.close();
|
server.close();
|
||||||
super.shutdown();
|
super.shutdown();
|
||||||
|
me.interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,13 +111,13 @@ public class UdpTransportManager extends AbstractTransportManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void send(URI endpoint, byte[] buf) throws IOException {
|
public void send(URI endpoint, byte[] buf) throws IOException {
|
||||||
DatagramSocket socket = new DatagramSocket();
|
// todo: investigate UDP socket reuse. It would save a little setup/teardown time wrt to the local socket.
|
||||||
|
try (DatagramSocket socket = new DatagramSocket()){
|
||||||
socket.setSoTimeout(soTimeout);
|
socket.setSoTimeout(soTimeout);
|
||||||
InetAddress dest = InetAddress.getByName(endpoint.getHost());
|
InetAddress dest = InetAddress.getByName(endpoint.getHost());
|
||||||
DatagramPacket payload = new DatagramPacket(buf, buf.length, dest, endpoint.getPort());
|
DatagramPacket payload = new DatagramPacket(buf, buf.length, dest, endpoint.getPort());
|
||||||
socket.send(payload);
|
socket.send(payload);
|
||||||
// todo: investigate UDP socket reuse. It would save a little setup/teardown time wrt to the local socket.
|
}
|
||||||
socket.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void debug(byte[] jsonBytes) {
|
private void debug(byte[] jsonBytes) {
|
||||||
@ -96,4 +126,10 @@ public class UdpTransportManager extends AbstractTransportManager {
|
|||||||
LOGGER.debug("Received message ( bytes): " + receivedMessage);
|
LOGGER.debug("Received message ( bytes): " + receivedMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startEndpoint() {
|
||||||
|
me.start();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.gossip.transport.udp;
|
package org.apache.gossip.transport.udp;
|
||||||
|
|
||||||
import org.apache.gossip.GossipSettings;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class UdpTransportIntegrationTest {
|
public class UdpTransportIntegrationTest {
|
||||||
|
|
||||||
// It's currently impossible to create a UdpTransportManager without bringing up an entire stack.
|
// It's currently impossible to create a UdpTransportManager without bringing up an entire stack.
|
||||||
|
1
pom.xml
1
pom.xml
@ -58,6 +58,7 @@
|
|||||||
<module>gossip-base</module>
|
<module>gossip-base</module>
|
||||||
<module>gossip-transport-udp</module>
|
<module>gossip-transport-udp</module>
|
||||||
<module>gossip-protocol-jackson</module>
|
<module>gossip-protocol-jackson</module>
|
||||||
|
<module>gossip-itest</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<description>A peer to peer cluster discovery service</description>
|
<description>A peer to peer cluster discovery service</description>
|
||||||
|
Reference in New Issue
Block a user