Skip to content

Commit 12fd1db

Browse files
BenHuddlestondaverigby
authored andcommitted
Revert "MB-36578: [BP] Dereference cookie when creating DCP conn with same name"
This reverts commit 5b0a350. After further investigation it was determined that the issue (MB-36451) of not dereferencing the cookie of DCP connections can be a symptom of MB-31495 and the code appears to be correct. As such, this change is unnecessary. Change-Id: I30c40f21fb0ce52bc6f3e3bb54063f61d7afe591 Reviewed-on: http://review.couchbase.org/116955 Tested-by: Build Bot <[email protected]> Well-Formed: Build Bot <[email protected]> Reviewed-by: Dave Rigby <[email protected]>
1 parent 015f6c2 commit 12fd1db

File tree

3 files changed

+59
-192
lines changed

3 files changed

+59
-192
lines changed

engines/ep/src/dcp/dcpconnmap.cc

Lines changed: 59 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -61,60 +61,42 @@ DcpConnMap::~DcpConnMap() {
6161
LOG(EXTENSION_LOG_NOTICE, "Deleted dcpConnMap_");
6262
}
6363

64-
std::shared_ptr<ConnHandler> DcpConnMap::checkForAndRemoveExistingConn(
65-
LockHolder& lh,
66-
const void* cookie,
67-
const std::string& name,
68-
const std::string& connType) {
69-
/*
70-
* If we request a connection of the same name then mark the existing
71-
* connection as "want to disconnect" and erase it from the map. The caller
72-
* will put it in deadConnections for us after it cancels associated
73-
* background tasks as we do that outside of the connsLock.
74-
*/
75-
auto oldConnection = findByName_UNLOCKED(lh, name);
76-
if (oldConnection) {
77-
LOG(EXTENSION_LOG_NOTICE,
78-
"%s Disconnecting existing Dcp %s %s as it has the same "
79-
"name as a new connection %p",
80-
oldConnection->logHeader(), connType.c_str(), name.c_str(), cookie);
81-
oldConnection->setDisconnect();
82-
map_.erase(oldConnection->getCookie());
83-
}
84-
85-
return oldConnection;
86-
}
87-
88-
DcpConsumer* DcpConnMap::newConsumer(const void* cookie,
89-
const std::string& name) {
90-
DcpConsumer* result = nullptr;
91-
std::shared_ptr<ConnHandler> oldConnection;
64+
DcpConsumer *DcpConnMap::newConsumer(const void* cookie,
65+
const std::string &name)
66+
{
67+
LockHolder lh(connsLock);
9268

9369
std::string conn_name("eq_dcpq:");
9470
conn_name.append(name);
9571

96-
{
97-
LockHolder lh(connsLock);
98-
const auto& iter = map_.find(cookie);
99-
if (iter != map_.end()) {
100-
iter->second->setDisconnect();
101-
LOG(EXTENSION_LOG_NOTICE,
102-
"Failed to create Dcp Consumer because connection "
103-
"(%p) already exists.", cookie);
104-
return nullptr;
105-
}
106-
107-
oldConnection = checkForAndRemoveExistingConn(
108-
lh, cookie, conn_name, "Consumer");
109-
auto consumer = std::make_shared<DcpConsumer>(engine, cookie, conn_name);
110-
111-
LOG(EXTENSION_LOG_INFO, "%s Connection created", consumer->logHeader());
72+
const auto& iter = map_.find(cookie);
73+
if (iter != map_.end()) {
74+
iter->second->setDisconnect();
75+
LOG(EXTENSION_LOG_NOTICE,
76+
"Failed to create Dcp Consumer because connection "
77+
"(%p) already exists.", cookie);
78+
return nullptr;
79+
}
11280

113-
result = consumer.get();
114-
map_[cookie] = std::move(consumer);
81+
/*
82+
* If we request a connection of the same name then
83+
* mark the existing connection as "want to disconnect".
84+
*/
85+
for (const auto& cookieToConn : map_) {
86+
if (cookieToConn.second->getName() == conn_name) {
87+
LOG(EXTENSION_LOG_NOTICE,
88+
"%s Disconnecting existing Dcp Consumer %p as it has the same "
89+
"name as a new connection %p",
90+
cookieToConn.second->logHeader(), cookieToConn.first, cookie);
91+
cookieToConn.second->setDisconnect();
92+
}
11593
}
11694

117-
disconnectConn(std::move(oldConnection));
95+
std::shared_ptr<DcpConsumer> dc =
96+
std::make_shared<DcpConsumer>(engine, cookie, conn_name);
97+
auto* result = dc.get();
98+
LOG(EXTENSION_LOG_INFO, "%s Connection created", dc->logHeader());
99+
map_[cookie] = std::move(dc);
118100
return result;
119101
}
120102

@@ -153,35 +135,43 @@ DcpProducer* DcpConnMap::newProducer(const void* cookie,
153135
const std::string& name,
154136
uint32_t flags,
155137
Collections::Filter filter) {
156-
DcpProducer* result = nullptr;
157-
std::shared_ptr<ConnHandler> oldConnection;
138+
LockHolder lh(connsLock);
158139

159140
std::string conn_name("eq_dcpq:");
160141
conn_name.append(name);
161-
{
162-
LockHolder lh(connsLock);
163142

164-
const auto& iter = map_.find(cookie);
165-
if (iter != map_.end()) {
166-
iter->second->setDisconnect();
167-
LOG(EXTENSION_LOG_NOTICE,
168-
"Failed to create Dcp Producer because connection "
169-
"(%p) already exists.", cookie);
170-
return nullptr;
171-
}
172-
173-
oldConnection = checkForAndRemoveExistingConn(
174-
lh, cookie, conn_name, "Producer");
175-
auto producer = std::make_shared<DcpProducer>(
176-
engine, cookie, conn_name, flags, std::move(filter), true /*startTask*/);
177-
178-
LOG(EXTENSION_LOG_INFO, "%s Connection created", producer->logHeader());
143+
const auto& iter = map_.find(cookie);
144+
if (iter != map_.end()) {
145+
iter->second->setDisconnect();
146+
LOG(EXTENSION_LOG_NOTICE,
147+
"Failed to create Dcp Producer because connection "
148+
"(%p) already exists.", cookie);
149+
return nullptr;
150+
}
179151

180-
result = producer.get();
181-
map_[cookie] = std::move(producer);
152+
/*
153+
* If we request a connection of the same name then
154+
* mark the existing connection as "want to disconnect".
155+
*/
156+
for (const auto& cookieToConn : map_) {
157+
if (cookieToConn.second->getName() == conn_name) {
158+
LOG(EXTENSION_LOG_NOTICE,
159+
"%s Disconnecting existing Dcp Producer %p as it has the same "
160+
"name as a new connection %p",
161+
cookieToConn.second->logHeader(), cookieToConn.first, cookie);
162+
cookieToConn.second->setDisconnect();
163+
}
182164
}
183165

184-
disconnectConn(std::move(oldConnection));
166+
auto producer = std::make_shared<DcpProducer>(engine,
167+
cookie,
168+
conn_name,
169+
flags,
170+
std::move(filter),
171+
true /*startTask*/);
172+
LOG(EXTENSION_LOG_INFO, "%s Connection created", producer->logHeader());
173+
auto* result = producer.get();
174+
map_[cookie] = std::move(producer);
185175

186176
return result;
187177
}
@@ -313,10 +303,6 @@ void DcpConnMap::disconnect(const void *cookie) {
313303
// acquire PassiveStream::buffer.bufMutex; and that could deadlock
314304
// in EPBucket::setVBucketState, via
315305
// PassiveStream::processBufferedMessages.
316-
disconnectConn(std::move(conn));
317-
}
318-
319-
void DcpConnMap::disconnectConn(std::shared_ptr<ConnHandler>&& conn) {
320306
if (conn) {
321307
auto producer = std::dynamic_pointer_cast<DcpProducer>(conn);
322308
if (producer) {
@@ -519,11 +505,6 @@ void DcpConnMap::consumerBatchSizeConfigChanged(size_t newValue) {
519505

520506
std::shared_ptr<ConnHandler> DcpConnMap::findByName(const std::string& name) {
521507
LockHolder lh(connsLock);
522-
return findByName_UNLOCKED(lh, name);
523-
}
524-
525-
std::shared_ptr<ConnHandler> DcpConnMap::findByName_UNLOCKED(
526-
LockHolder& lh, const std::string& name) {
527508
for (const auto& cookieToConn : map_) {
528509
// If the connection is NOT about to be disconnected
529510
// and the names match

engines/ep/src/dcp/dcpconnmap.h

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,6 @@ class DcpConnMap : public ConnMap {
4040

4141
~DcpConnMap();
4242

43-
/**
44-
* Checks for a connection with the same name and sets it to disconnected
45-
* whilst removing it from the map
46-
*
47-
* @param cookie Cookie representing the client
48-
* @param name Full name of the connection
49-
* @param connType Logging string (Producer/Consumer)
50-
* @return shared_ptr to the connection
51-
*/
52-
std::shared_ptr<ConnHandler> checkForAndRemoveExistingConn(
53-
LockHolder& lh,
54-
const void* cookie,
55-
const std::string& name,
56-
const std::string& connType);
57-
5843
/**
5944
* Find or build a dcp connection for the given cookie and with
6045
* the given name.
@@ -116,18 +101,8 @@ class DcpConnMap : public ConnMap {
116101
*/
117102
bool handleSlowStream(uint16_t vbid, const std::string &name);
118103

119-
/**
120-
* Disconnect the connection for the given cookie
121-
*/
122104
void disconnect(const void *cookie);
123105

124-
/**
125-
* ConnHandler specific disconnection.
126-
*
127-
* @param conn RValue conn to prevent any later use by caller
128-
*/
129-
void disconnectConn(std::shared_ptr<ConnHandler>&& conn);
130-
131106
void manageConnections();
132107

133108
bool canAddBackfillToActiveQ();
@@ -185,9 +160,6 @@ class DcpConnMap : public ConnMap {
185160
*/
186161
std::list<std::shared_ptr<ConnHandler>> deadConnections;
187162

188-
std::shared_ptr<ConnHandler> findByName_UNLOCKED(LockHolder& lh,
189-
const std::string& name);
190-
191163
/*
192164
* Change the value at which a DcpConsumer::Processor task will yield
193165
*/

engines/ep/tests/module_tests/dcp_test.cc

Lines changed: 0 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,16 +1879,6 @@ class ConnectionTest : public DCPTest,
18791879
*/
18801880
void processConsumerMutationsNearThreshold(bool beyondThreshold);
18811881

1882-
/**
1883-
* Tests that when we open a DCP connection with the same name as an
1884-
* existing one the old one is correctly put into
1885-
* DcpConnMap::deadConnections and de-referenced by manageConnections
1886-
*
1887-
* @param DCP Open flags so we can test any type of connection
1888-
*/
1889-
void testDCPConnectionWIthSameNameCorrectlyDereferencesOldOne(
1890-
uint32_t flags);
1891-
18921882
/* vbucket associated with this connection */
18931883
uint16_t vbid;
18941884
};
@@ -2107,82 +2097,6 @@ TEST_P(ConnectionTest, test_deadConnections) {
21072097
<< "Dead connections still remain";
21082098
}
21092099

2110-
void ConnectionTest::testDCPConnectionWIthSameNameCorrectlyDereferencesOldOne(
2111-
uint32_t flags) {
2112-
auto& connMap = engine->getDcpConnMap();
2113-
2114-
// 1) Create a new DCP connection
2115-
const void* cookie1 = create_mock_cookie();
2116-
2117-
// Cookie ref count is initialized to 1 (like it would be for an actual
2118-
// server connection)
2119-
ASSERT_EQ(1, get_number_of_mock_cookie_references(cookie1));
2120-
2121-
// Need to hit the engine level function because it will do the cookie ref
2122-
// counting only if the DCP Open is successful
2123-
ASSERT_EQ(ENGINE_SUCCESS,
2124-
engine->dcpOpen(cookie1,
2125-
0 /*opaque*/,
2126-
0 /*seqno*/,
2127-
flags /*flags*/,
2128-
"test_conn",
2129-
{} /*value*/));
2130-
2131-
// Should be able to find the connection with the given cookie
2132-
ASSERT_NE(nullptr, connMap.findByName("eq_dcpq:test_conn"));
2133-
EXPECT_EQ(2, get_number_of_mock_cookie_references(cookie1));
2134-
2135-
// 2) Create a new DCP connection with the same name
2136-
const void* cookie2 = create_mock_cookie();
2137-
ASSERT_EQ(1, get_number_of_mock_cookie_references(cookie2));
2138-
ASSERT_EQ(ENGINE_SUCCESS,
2139-
engine->dcpOpen(cookie2,
2140-
0 /*opaque*/,
2141-
0 /*seqno*/,
2142-
flags,
2143-
"test_conn",
2144-
{} /*value*/));
2145-
2146-
// Should be able to find the connection with the given cookie. We will
2147-
// always return the new connections here as we skip disconnecting
2148-
// connections when we search by name (and we should have marked the
2149-
// original connection as disconnecting.
2150-
auto conn = connMap.findByName("eq_dcpq:test_conn");
2151-
ASSERT_TRUE(conn);
2152-
EXPECT_EQ(cookie2, conn->getCookie());
2153-
2154-
EXPECT_FALSE(connMap.isDeadConnectionsEmpty());
2155-
EXPECT_EQ(2, get_number_of_mock_cookie_references(cookie1));
2156-
EXPECT_EQ(2, get_number_of_mock_cookie_references(cookie2));
2157-
2158-
// Manage connections is called whenever we have some connection
2159-
// notification work to do. This is where we deal with deadConnections and
2160-
// de-reference the cookie.
2161-
connMap.manageConnections();
2162-
EXPECT_TRUE(connMap.isDeadConnectionsEmpty());
2163-
EXPECT_EQ(1, get_number_of_mock_cookie_references(cookie1));
2164-
EXPECT_EQ(2, get_number_of_mock_cookie_references(cookie2));
2165-
2166-
connMap.disconnect(cookie2);
2167-
2168-
destroy_mock_cookie(cookie1);
2169-
destroy_mock_cookie(cookie2);
2170-
}
2171-
2172-
TEST_P(ConnectionTest, NewDcpConsumerWithSameNameCorrectlyShutsdownOldOne) {
2173-
testDCPConnectionWIthSameNameCorrectlyDereferencesOldOne(0 /*no flags*/);
2174-
}
2175-
2176-
TEST_P(ConnectionTest, NewDcpProducerWithSameNameCorrectlyShutsdownOldOne) {
2177-
testDCPConnectionWIthSameNameCorrectlyDereferencesOldOne(
2178-
DCP_OPEN_PRODUCER);
2179-
}
2180-
2181-
TEST_P(ConnectionTest, NewDcpNotifierWithSameNameCorrectlyShutsdownOldOne) {
2182-
testDCPConnectionWIthSameNameCorrectlyDereferencesOldOne(
2183-
DCP_OPEN_NOTIFIER);
2184-
}
2185-
21862100
TEST_P(ConnectionTest, test_mb23637_findByNameWithConnectionDoDisconnect) {
21872101
MockDcpConnMap connMap(*engine);
21882102
connMap.initialize();

0 commit comments

Comments
 (0)