Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into master-ZOOKEEPER-3061
Browse files Browse the repository at this point in the history
  • Loading branch information
cpoerschke committed Jul 10, 2018
2 parents 1840c2b + 5fdd70a commit 1399682
Show file tree
Hide file tree
Showing 14 changed files with 72 additions and 42 deletions.
4 changes: 2 additions & 2 deletions docs/releasenotes.html
Original file line number Diff line number Diff line change
Expand Up @@ -300,11 +300,11 @@ <h3 class="h4">Migrating Client Code</h3>
<h4>Watch Management</h4>
<p>
In previous releases of ZooKeeper any watches registered by clients were lost if the client lost a connection to a ZooKeeper server.
This meant that developers had to track watches they were interested in and reregister them if a session disconnect event was recieved.
This meant that developers had to track watches they were interested in and reregister them if a session disconnect event was received.
In this release the client library tracks watches that a client has registered and reregisters the watches when a connection is made to a new server.
Applications that still manually reregister interest should continue working properly as long as they are able to handle unsolicited watches.
For example, an old application may register a watch for /foo and /goo, lose the connection, and reregister only /goo.
As long as the application is able to recieve a notification for /foo, (probably ignoring it) it does not need to be changed.
As long as the application is able to receive a notification for /foo, (probably ignoring it) it does not need to be changed.
One caveat to the watch management: it is possible to miss an event for the creation and deletion of a znode if watching for creation and both the create and delete happens while the client is disconnected from ZooKeeper.
</p>
<p>
Expand Down
2 changes: 1 addition & 1 deletion src/c/acinclude.m4
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# aminclude.m4 file and a compatible doxygen configuration file. Defines the
# following public macros:
#
# DX_???_FEATURE(ON|OFF) - control the default setting fo a Doxygen feature.
# DX_???_FEATURE(ON|OFF) - control the default setting of a Doxygen feature.
# Supported features are 'DOXYGEN' itself, 'DOT' for generating graphics,
# 'HTML' for plain HTML, 'CHM' for compressed HTML help (for MS users), 'CHI'
# for generating a seperate .chi file by the .chm file, and 'MAN', 'RTF',
Expand Down
24 changes: 1 addition & 23 deletions src/c/src/zookeeper.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,6 @@ static void cleanup_bufs(zhandle_t *zh,int callCompletion,int rc);
static int disable_conn_permute=0; // permute enabled by default
static struct sockaddr_storage *addr_rw_server = 0;

static __attribute__((unused)) void print_completion_queue(zhandle_t *zh);

static void *SYNCHRONOUS_MARKER = (void*)&SYNCHRONOUS_MARKER;
static int isValidPath(const char* path, const int flags);

Expand Down Expand Up @@ -2530,26 +2528,6 @@ int api_epilog(zhandle_t *zh,int rc)
return rc;
}

static __attribute__((unused)) void print_completion_queue(zhandle_t *zh)
{
completion_list_t* cptr;

if(logLevel<ZOO_LOG_LEVEL_DEBUG) return;

fprintf(LOGSTREAM,"Completion queue: ");
if (zh->sent_requests.head==0) {
fprintf(LOGSTREAM,"empty\n");
return;
}

cptr=zh->sent_requests.head;
while(cptr){
fprintf(LOGSTREAM,"%d,",cptr->xid);
cptr=cptr->next;
}
fprintf(LOGSTREAM,"end\n");
}

//#ifdef THREADED
// IO thread queues session events to be processed by the completion thread
static int queue_session_event(zhandle_t *zh, int state)
Expand Down Expand Up @@ -4357,7 +4335,7 @@ int zoo_add_auth(zhandle_t *zh,const char* scheme,const char* cert,
static const char* format_endpoint_info(const struct sockaddr_storage* ep)
{
static char buf[128] = { 0 };
char addrstr[128] = { 0 };
char addrstr[INET6_ADDRSTRLEN] = { 0 };
void *inaddr;
#ifdef _WIN32
char * addrstring;
Expand Down
2 changes: 1 addition & 1 deletion src/java/main/org/apache/jute/OutputArchive.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import java.util.TreeMap;

/**
* Interface that alll the serializers have to implement.
* Interface that all the serializers have to implement.
*
*/
public interface OutputArchive {
Expand Down
2 changes: 1 addition & 1 deletion src/java/main/org/apache/zookeeper/ClientCnxnSocket.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ void updateLastSendAndHeard() {
protected void readLength() throws IOException {
int len = incomingBuffer.getInt();
if (len < 0 || len >= packetLen) {
throw new IOException("Packet len" + len + " is out of range!");
throw new IOException("Packet len " + len + " is out of range!");
}
incomingBuffer = ByteBuffer.allocate(len);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public CliCommand parse(String[] cmdArgs) throws CliParseException {
@Override
public boolean exec() throws CliException {
//if neither option -n or -b is specified, we delete
// the quota node for thsi node.
// the quota node for this node.
String path = args[1];
try {
if (cl.hasOption("b")) {
Expand Down
2 changes: 1 addition & 1 deletion src/java/main/org/apache/zookeeper/server/DataTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public class DataTree {
.substring(procZookeeper.length() + 1);

/**
* the path trie that keeps track fo the quota nodes in this datatree
* the path trie that keeps track of the quota nodes in this datatree
*/
private final PathTrie pTrie = new PathTrie();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ public void processRequest(Request request) {
}

KeeperException ke = request.getException();
if (ke instanceof SessionMovedException) {
throw ke;
}
if (ke != null && request.type != OpCode.multi) {
throw ke;
}
Expand Down Expand Up @@ -228,6 +231,9 @@ public void processRequest(Request request) {
break;
case OpCode.error:
subResult = new ErrorResult(subTxnResult.err) ;
if (subTxnResult.err == Code.SESSIONMOVED.intValue()) {
throw new SessionMovedException();
}
break;
default:
throw new IOException("Invalid type of op");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ public static void startInstance(InstanceManager im, String quorumHostPort, int
/**
* Stop an instance of the quorumPeer
* @param im the manager of the instance
* @param index the zero based index fo the server to stop
* @param index the zero based index of the server to stop
* @throws InterruptedException
* @throws KeeperException
* @throws NoAssignmentException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public void testLoad() throws Exception {
hdr = itr.getHeader();
expectedZxid++;
Assert.assertTrue("not the same transaction. lastZxid=" + lastZxid + ", zxid=" + hdr.getZxid(), lastZxid != hdr.getZxid());
Assert.assertTrue("excepting next transaction. expected=" + expectedZxid + ", retreived=" + hdr.getZxid(), (hdr.getZxid() == expectedZxid));
Assert.assertTrue("excepting next transaction. expected=" + expectedZxid + ", retrieved=" + hdr.getZxid(), (hdr.getZxid() == expectedZxid));
lastZxid = hdr.getZxid();
}while(itr.next());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,10 @@ public void processResult(int rc, String path, Object ctx,
}
for (int i = 0; i < res.results.size(); i++) {
OpResult opResult = res.results.get(i);
Assert.assertTrue("Did't recieve proper error response",
Assert.assertTrue("Did't receive proper error response",
opResult instanceof ErrorResult);
ErrorResult errRes = (ErrorResult) opResult;
Assert.assertEquals("Did't recieve proper error code",
Assert.assertEquals("Did't receive proper error code",
expectedResultCodes.get(i).intValue(), errRes.getErr());
}
} else {
Expand Down
58 changes: 52 additions & 6 deletions src/java/test/org/apache/zookeeper/test/QuorumTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,52 @@ public void process(WatchedEvent event) {
}
}

/**
* Make sure the previous connection closed after session move within
* multiop.
*
* @throws IOException
* @throws InterruptedException
* @throws KeeperException
*/
@Test
public void testSessionMovedWithMultiOp() throws Exception {
String hostPorts[] = qb.hostPort.split(",");
DisconnectableZooKeeper zk = new DisconnectableZooKeeper(hostPorts[0],
ClientBase.CONNECTION_TIMEOUT, new Watcher() {
public void process(WatchedEvent event) {
}});
zk.multi(Arrays.asList(
Op.create("/testSessionMovedWithMultiOp", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL)
));

// session moved to the next server
ZooKeeper zknew = new ZooKeeper(hostPorts[1],
ClientBase.CONNECTION_TIMEOUT,
new Watcher() {public void process(WatchedEvent event) {
}},
zk.getSessionId(),
zk.getSessionPasswd());
zknew.multi(Arrays.asList(
Op.create("/testSessionMovedWithMultiOp-1", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL)
));

// try to issue the multi op again from the old connection
// expect to have ConnectionLossException instead of keep
// getting SessionMovedException
try {
zk.multi(Arrays.asList(
Op.create("/testSessionMovedWithMultiOp-Failed",
new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL)
));
Assert.fail("Should have lost the connection");
} catch (KeeperException.ConnectionLossException e) {
}

zk.close();
zknew.close();
}

/**
* Connect to two different servers with two different handles using the same session and
* make sure we cannot do any changes.
Expand Down Expand Up @@ -295,8 +341,8 @@ ClientBase.CONNECTION_TIMEOUT, new DiscoWatcher(),
zk.close();
}

/**
* See ZOOKEEPER-790 for details
/**
* See ZOOKEEPER-790 for details
* */
@Test
public void testFollowersStartAfterLeader() throws Exception {
Expand All @@ -310,18 +356,18 @@ public void testFollowersStartAfterLeader() throws Exception {

// break the quorum
qu.shutdown(index);

// try to reestablish the quorum
qu.start(index);

// Connect the client after services are restarted (otherwise we would get
// SessionExpiredException as the previous local session was not persisted).
ZooKeeper zk = new ZooKeeper(
"127.0.0.1:" + qu.getPeer((index == 1)?2:1).peer.getClientPort(),
ClientBase.CONNECTION_TIMEOUT, watcher);

try{
watcher.waitForConnected(CONNECTION_TIMEOUT);
watcher.waitForConnected(CONNECTION_TIMEOUT);
} catch(TimeoutException e) {
Assert.fail("client could not connect to reestablished quorum: giving up after 30+ seconds.");
}
Expand All @@ -334,7 +380,7 @@ public void testFollowersStartAfterLeader() throws Exception {
/**
* Tests if a multiop submitted to a non-leader propagates to the leader properly
* (see ZOOKEEPER-1124).
*
*
* The test works as follows. It has a client connect to a follower and submit a multiop
* to the follower. It then verifies that the multiop successfully gets committed by the leader.
*
Expand Down
2 changes: 1 addition & 1 deletion src/recipes/lock/src/c/acinclude.m4
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# aminclude.m4 file and a compatible doxygen configuration file. Defines the
# following public macros:
#
# DX_???_FEATURE(ON|OFF) - control the default setting fo a Doxygen feature.
# DX_???_FEATURE(ON|OFF) - control the default setting of a Doxygen feature.
# Supported features are 'DOXYGEN' itself, 'DOT' for generating graphics,
# 'HTML' for plain HTML, 'CHM' for compressed HTML help (for MS users), 'CHI'
# for generating a seperate .chi file by the .chm file, and 'MAN', 'RTF',
Expand Down
2 changes: 1 addition & 1 deletion src/recipes/queue/src/c/acinclude.m4
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# aminclude.m4 file and a compatible doxygen configuration file. Defines the
# following public macros:
#
# DX_???_FEATURE(ON|OFF) - control the default setting fo a Doxygen feature.
# DX_???_FEATURE(ON|OFF) - control the default setting of a Doxygen feature.
# Supported features are 'DOXYGEN' itself, 'DOT' for generating graphics,
# 'HTML' for plain HTML, 'CHM' for compressed HTML help (for MS users), 'CHI'
# for generating a seperate .chi file by the .chm file, and 'MAN', 'RTF',
Expand Down

0 comments on commit 1399682

Please sign in to comment.