[
https://issues.apache.org/jira/browse/ZOOKEEPER-2466?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15370027#comment-15370027
]
Michael Han commented on ZOOKEEPER-2466:
----------------------------------------
I see, I got the logic wrong - just checked Java code and it does same thing
(prefer RW server to read only server) by throwing an exception.
bq. That's one thing that is confusing me here, if it is finds a read-write
server, then it should stick to it and transition away from read-only.
I think the C code does this - if ping_rw_server(zh) != 0 then we find a rw
server and the server address can be retrieved through addrvec_next(&zh->addrs,
&zh->addr_cur), because the ping_rw_server uses the addrvec_peek to try next
address. What handle_error does is to transition away from the current server
(read-only) to the new read-write server, by cleaning up the current state (as
if there is an error) and shift the next address to try to the next address,
which is validated by ping_rw_server(zh) to be a read-write server.
So I guess we can still remove addrvec_next in handle_error and explicitly call
addrvec_next:
{code}
if (ping_rw_server(zh)) {
struct sockaddr_storage addr;
addrvec_peek(&zh->addrs, &addr);
zh->ping_rw_timeout = MIN_RW_TIMEOUT;
LOG_INFO(LOGCALLBACK(zh),
"r/w server found at %s",
format_endpoint_info(&addr));
handle_error(zh, ZRWSERVERFOUND);
addrvec_next(&zh->addrs, &zh->addr_cur);
} else {
addrvec_next(&zh->addrs, NULL);
}
{code}
> Client skips servers when trying to connect
> -------------------------------------------
>
> Key: ZOOKEEPER-2466
> URL: https://issues.apache.org/jira/browse/ZOOKEEPER-2466
> Project: ZooKeeper
> Issue Type: Bug
> Components: c client
> Reporter: Flavio Junqueira
> Assignee: Flavio Junqueira
> Priority: Critical
> Fix For: 3.5.3, 3.6.0
>
>
> I've been looking at {{Zookeeper_simpleSystem::testFirstServerDown}} and I
> observed the following behavior. The list of servers to connect contains two
> servers, let's call them S1 and S2. The client never connects, but the odd
> bit is the sequence of servers that the client tries to connect to:
> {noformat}
> S1
> S2
> S1
> S1
> S1
> <keeps repeating S1>
> {noformat}
> It intrigued me that S2 is only tried once and never again. Checking the
> code, here is what happens. Initially, {{zh->reconfig}} is 1, so in
> {{zoo_cycle_next_server}} we return an address from
> {{get_next_server_in_reconfig}}, which is taken from {{zh->addrs_new}} in
> this test case. The attempt to connect fails, and {{handle_error}} is invoked
> in the error handling path. {{handle_error}} actually invokes
> {{addrvec_next}} which changes the address pointer to the next server on the
> list.
> After two attempts, it decides that it has tried all servers in
> {{zoo_cycle_next_server}} and sets {{zh->reconfig}} to zero. Once
> {{zh->reconfig == 0}}, we have that each call to {{zoo_cycle_next_server}}
> moves the address pointer to the next server in {{zh->addrs}}. But, given
> that {{handle_error}} also moves the pointer to the next server, we end up
> moving the pointer ahead twice upon every failed attempt to connect, which is
> wrong.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)