Skip to content

Commit 7a878a4

Browse files
authored
Introduce hooks to implement refreshing the otherNodes array. (#740)
This way we allow extensions to pg_auto_failover to implement specific processing when the otherNodes array changes, when that's needed.
1 parent 99ae2b8 commit 7a878a4

3 files changed

Lines changed: 86 additions & 12 deletions

File tree

src/bin/pg_autoctl/keeper.c

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,9 +2039,7 @@ keeper_refresh_other_nodes(Keeper *keeper, bool forceCacheInvalidation)
20392039
Monitor *monitor = &(keeper->monitor);
20402040
KeeperConfig *config = &(keeper->config);
20412041

2042-
NodeAddressArray *otherNodesArray = &(keeper->otherNodes);
20432042
NodeAddressArray newNodesArray = { 0 };
2044-
NodeAddressArray diffNodesArray = { 0 };
20452043

20462044
int64_t nodeId = keeper->state.current_node_id;
20472045

@@ -2064,30 +2062,83 @@ keeper_refresh_other_nodes(Keeper *keeper, bool forceCacheInvalidation)
20642062
}
20652063
}
20662064

2065+
/*
2066+
* In case of success, copy the current nodes array to the keeper's cache.
2067+
*/
2068+
bool success =
2069+
keeper_call_refresh_hooks(keeper, &newNodesArray, forceCacheInvalidation);
2070+
2071+
if (success)
2072+
{
2073+
keeper->otherNodes = newNodesArray;
2074+
}
2075+
2076+
return success;
2077+
}
2078+
2079+
2080+
/*
2081+
* keeper_call_refresh_hooks loops over the KeeperNodesArrayRefreshArray and
2082+
* calls each hook in turn. It returns true when all the hooks have returned
2083+
* true.
2084+
*/
2085+
bool
2086+
keeper_call_refresh_hooks(Keeper *keeper,
2087+
NodeAddressArray *newNodesArray,
2088+
bool forceCacheInvalidation)
2089+
{
2090+
bool success = true;
2091+
2092+
for (int index = 0; KeeperRefreshHooks[index]; index++)
2093+
{
2094+
KeeperNodesArrayRefreshFunction hookFun = KeeperRefreshHooks[index];
2095+
2096+
bool ret = (*hookFun)(keeper, newNodesArray, forceCacheInvalidation);
2097+
2098+
success = success && ret;
2099+
}
2100+
2101+
return success;
2102+
}
2103+
2104+
2105+
/*
2106+
* keeper_refresh_hba is a KeeperNodesArrayRefreshFunction that adds new
2107+
* entries in the Postgres HBA file for new nodes that have been added to our
2108+
* group.
2109+
*/
2110+
bool
2111+
keeper_refresh_hba(Keeper *keeper,
2112+
NodeAddressArray *newNodesArray,
2113+
bool forceCacheInvalidation)
2114+
{
2115+
NodeAddressArray *otherNodesArray = &(keeper->otherNodes);
2116+
NodeAddressArray diffNodesArray = { 0 };
2117+
20672118
/* compute nodes that need an HBA change (new ones, new hostnames) */
20682119
if (forceCacheInvalidation)
20692120
{
2070-
diffNodesArray = newNodesArray;
2121+
diffNodesArray = *newNodesArray;
20712122
}
20722123
else
20732124
{
2074-
(void) diff_nodesArray(otherNodesArray, &newNodesArray, &diffNodesArray);
2125+
(void) diff_nodesArray(otherNodesArray, newNodesArray, &diffNodesArray);
20752126
}
20762127

20772128
/*
20782129
* When we're alone in the group, and also when there's no change, then we
20792130
* are done here already.
20802131
*/
2081-
if (newNodesArray.count == 0 || diffNodesArray.count == 0)
2132+
if (newNodesArray->count == 0 || diffNodesArray.count == 0)
20822133
{
20832134
/* refresh the keeper's cache with the current other nodes array */
2084-
keeper->otherNodes = newNodesArray;
2135+
keeper->otherNodes = *newNodesArray;
20852136
return true;
20862137
}
20872138

20882139
log_info("Fetched current list of %d other nodes from the monitor "
20892140
"to update HBA rules, including %d changes.",
2090-
newNodesArray.count, diffNodesArray.count);
2141+
newNodesArray->count, diffNodesArray.count);
20912142

20922143
/*
20932144
* We have a new list of other nodes, update the HBA file. We only update
@@ -2103,11 +2154,6 @@ keeper_refresh_other_nodes(Keeper *keeper, bool forceCacheInvalidation)
21032154
return false;
21042155
}
21052156

2106-
/*
2107-
* In case of success, copy the current nodes array to the keeper's cache.
2108-
*/
2109-
keeper->otherNodes = newNodesArray;
2110-
21112157
return true;
21122158
}
21132159

src/bin/pg_autoctl/keeper.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,32 @@ bool keeper_config_accept_new(Keeper *keeper, KeeperConfig *newConfig);
8181
*/
8282
typedef bool (*KeeperReloadFunction)(Keeper *keeper, bool firstLoop, bool doInit);
8383

84+
/*
85+
* When updating the list of other nodes (a NodesArray) after calling
86+
* node_active, the keeper needs to implement specific actions such as editing
87+
* the HBA rules to allow new nodes to connect.
88+
*/
89+
typedef bool (*KeeperNodesArrayRefreshFunction)(Keeper *keeper,
90+
NodeAddressArray *newNodesArray,
91+
bool forceCacheInvalidation);
92+
8493
/* src/bin/pg_autoctl/service_keeper.c */
8594
extern KeeperReloadFunction *KeeperReloadHooks;
95+
extern KeeperNodesArrayRefreshFunction *KeeperRefreshHooks;
8696

8797
void keeper_call_reload_hooks(Keeper *keeper, bool firstLoop, bool doInit);
8898
bool keeper_reload_configuration(Keeper *keeper, bool firstLoop, bool doInit);
8999

100+
bool keeper_call_refresh_hooks(Keeper *keeper,
101+
NodeAddressArray *newNodesArray,
102+
bool forceCacheInvalidation);
103+
bool keeper_refresh_hba(Keeper *keeper,
104+
NodeAddressArray *newNodesArray,
105+
bool forceCacheInvalidation);
106+
90107
bool keeper_read_nodes_from_file(Keeper *keeper, NodeAddressArray *nodesArray);
91108
bool keeper_get_primary(Keeper *keeper, NodeAddress *primaryNode);
92109
bool keeper_get_most_advanced_standby(Keeper *keeper, NodeAddress *primaryNode);
93110

111+
94112
#endif /* KEEPER_H */

src/bin/pg_autoctl/service_keeper.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ KeeperReloadFunction KeeperReloadHooksArray[] = {
4444

4545
KeeperReloadFunction *KeeperReloadHooks = KeeperReloadHooksArray;
4646

47+
/* list of hooks to run to update a list of nodes, at node active time */
48+
KeeperNodesArrayRefreshFunction KeeperNodesArrayRefreshArray[] = {
49+
&keeper_refresh_hba,
50+
NULL
51+
};
52+
53+
KeeperNodesArrayRefreshFunction *KeeperRefreshHooks =
54+
KeeperNodesArrayRefreshArray;
55+
56+
4757
static bool service_keeper_node_active(Keeper *keeper, bool doInit);
4858
static void check_for_network_partitions(Keeper *keeper);
4959
static bool is_network_healthy(Keeper *keeper);

0 commit comments

Comments
 (0)