8000 fix long precondition in removeServer (#12080) · RtiWeb/arangodb@c900676 · GitHub
[go: up one dir, main page]

Skip to content

Commit c900676

Browse files
kvahedKVS85
andauthored
fix long precondition in removeServer (arangodb#12080)
* fix long precondition in removeServer * lint, lint, ... * broken * Update CHANGELOG Co-authored-by: Vadim <vadim@arangodb.com>
1 parent 64cc0ae commit c900676

File tree

2 files changed

+63
-26
lines changed

2 files changed

+63
-26
lines changed

CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
v3.6.5 (XXXX-XX-XX)
22
-------------------
33

4+
* Fix untenable ultra precondition for removeServer.
5+
46
* Fixed that the hotbackup agency lock is released under all circumstances using
57
scope guards. This addresses a rare case in which the lock was left behind.
68

js/actions/api-cluster.js

Lines changed: 61 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,11 @@ actions.defineHttp({
7575
return;
7676
}
7777

78-
if (serverId.substr(0, 4) !== 'CRDN' && serverId.substr(0, 4) !== 'PRMR') {
79-
actions.resultError(req, res, actions.HTTP_BAD,
80-
'couldn\'t determine role for server id ' + serverId);
78+
let isCoordinator = serverId.substr(0, 4) === 'CRDN';
79+
let isDBServer = serverId.substr(0, 4) === 'PRMR';
80+
if (!isCoordinator && !isDBServer) {
81+
actions.resultError(
82+
req, res, actions.HTTP_BAD, 'couldn\'t determine role for server id ' + serverId);
8183
return;
8284
}
8385

@@ -87,37 +89,41 @@ actions.defineHttp({
8789
while (++count <= 60) {
8890
// need to make sure it is not responsible for anything
8991
used = [];
90-
let preconditions = reducePlanServers(function (data, agencyKey, servers) {
91-
data[agencyKey] = {'old': servers};
92-
if (servers.indexOf(serverId) !== -1) {
93-
used.push(agencyKey);
94-
}
95-
return data;
96-
}, {});
97-
preconditions = reduceCurrentServers(function (data, agencyKey, servers) {
98-
data[agencyKey] = {'old': servers};
99-
if (servers.indexOf(serverId) !== -1) {
100-
used.push(agencyKey);
101-
}
102-
return data;
103-
}, preconditions);
92+
let curVersion = amongCurrentShardsOrVersion(serverId);
93+
if (curVersion === 0) {
94+
wait(1.0);
95+
continue;
96+
}
97+
let planVersion = amongPlanShardsOrVersion(serverId);
98+
if (planVersion === 0) {
99+
wait(1.0);
100+
continue;
101+
}
104102

103+
var preconditions = {};
104+
preconditions['/arango/Plan/Version'] = {'old': planVersion};
105+
preconditions['/arango/Current/Version'] = {'old': curVersion};
105106
preconditions['/arango/Supervision/Health/' + serverId + '/Status'] = {'old': 'FAILED'};
106-
preconditions["/arango/Supervision/DBServers/" + serverId]
107-
= { "oldEmpty": true };
107+
if (isDBServer) {
108+
preconditions["/arango/Supervision/DBServers/" + serverId] = { "oldEmpty": true };
109+
}
108110

109-
if (!checkServerLocked(serverId) && used.length === 0) {
111+
if (!checkServerLocked(serverId)) {
110112
let operations = {};
111-
operations['/arango/Plan/Coordinators/' + serverId] = {'op': 'delete'};
112-
operations['/arango/Plan/DBServers/' + serverId] = {'op': 'delete'};
113+
if (isCoordinator) {
114+
operations['/arango/Plan/Coordinators/' + serverId] = {'op': 'delete'};
115+
operations['/arango/Current/Coordinators/' + serverId] = {'op': 'delete'};
116+
} else {
117+
operations['/arango/Plan/DBServers/' + serverId] = {'op': 'delete'};
118+
operations['/arango/Current/DBServers/' + serverId] = {'op': 'delete'};
119+
}
113120
operations['/arango/Current/ServersRegistered/' + serverId] = {'op': 'delete'};
114-
operations['/arango/Current/DBServers/' + serverId] = {'op': 'delete'};
115-
operations['/arango/Current/Coordinators/' + serverId] = {'op': 'delete'};
116121
operations['/arango/Supervision/Health/' + serverId] = {'op': 'delete'};
117122
operations['/arango/Target/MapUniqueToShortID/' + serverId] = {'op': 'delete'};
118123
operations['/arango/Current/ServersKnown/' + serverId] = {'op': 'delete'};
119124
operations['/arango/Target/RemovedServers/' + serverId] = {'op': 'set', 'new': (new Date()).toISOString()};
120125

126+
console.info ([[operations, preconditions]]);
121127
try {
122128
global.ArangoAgency.write([[operations, preconditions]]);
123129
actions.resultOk(req, res, actions.HTTP_OK, true);
@@ -141,8 +147,7 @@ actions.defineHttp({
141147
wait(1.0);
142148
} // while count
143149
actions.resultError(req, res, actions.HTTP_PRECONDITION_FAILED,
144-
'the server not failed, locked or is still in use at the following '
145-
+ 'locations: ' + JSON.stringify(used));
150+
'the server is either not failed or is locked or is still in use.');
146151
}
147152
});
148153

@@ -638,6 +643,36 @@ function reducePlanServers (reducer, data) {
638643
}, data);
639644
}
640645

646+
function amongCurrentShardsOrVersion (myId) {
647+
var current = ArangoAgency.get('Current').arango.Current;
648+
for (const [name,database] of Object.entries(current.Collections)) {
649+
for (const [name,collection] of Object.entries(database)) {
650+
for (const [name,shard] of Object.entries(collection)) {
651+
if (shard.servers.indexOf(myId) > -1) {
652+
// i hit a shard with my id listed
653+
return 0;
654+
}
655+
}
656+
}
657+
}
658+
return current.Version;
659+
}
660+
661+
function amongPlanShardsOrVersion (myId) {
662+
var plan = ArangoAgency.get('Plan').arango.Plan;
663+
for (const [name,database] of Object.entries(plan.Collections)) {
664+
for (const [name,collection] of Object.entries(database)) {
665+
for (const [name,shard] of Object.entries(collection.shards)) {
666+
if (shard.indexOf(myId) > -1) {
667+
// i hit a shard with my id listed
668+
return 0;
669+
}
670+
}
671+
}
672+
}
673+
return plan.Version;
674+
}
675+
641676
function reduceCurrentServers (reducer, data) {
642677
var databases = ArangoAgency.get('Current/Collections');
643678
databases = databases.arango.Current.Collections;

0 commit comments

Comments
 (0)
0