提交 854c4b84 编写于 作者: N Ning Yu 提交者: Hubert Zhang

ic-proxy: classify peer addresses

The peer addresses are specified with the GUC
gp_interconnect_proxy_addresses, it can be reloaded on SIGHUP, we used
to only care about the newly added ones, however it is also possible for
the user to modify them, or even remove some of them.

So now we add the logic to classify the addresses after parsing the GUC,
we can tell whether an address is added, removed, or modified.

The handling of the classified addresses will be done in the next
commit.
上级 40facdb1
......@@ -55,4 +55,37 @@ ic_proxy_build_server_sock_path(char *buf, size_t bufsize)
PostPortNumber, PostmasterPid);
}
/*
* Free a list.
*
* The difference with list_free() is we always return NIL.
*/
static inline List *
ic_proxy_list_free(List *list)
{
list_free(list);
return NIL;
}
/*
* Free a list and the cells.
*
* The cells must be allocated with the ic_proxy_alloc() / ic_proxy_new()
* allocators.
*
* Always return NIL.
*/
static inline List *
ic_proxy_list_free_deep(List *list)
{
ListCell *cell;
foreach(cell, list)
{
ic_proxy_free(lfirst(cell));
}
return ic_proxy_list_free(list);
}
#endif /* IC_PROXY_H */
......@@ -28,10 +28,32 @@
/*
* List<ICProxyAddr *>, the addresses list.
* List<ICProxyAddr *>, the current addresses list.
*/
List *ic_proxy_addrs = NIL;
/*
* List<ICProxyAddr *>, the previous addresses list.
*
* It holds the memory of all the addresses, so the classified lists can only
* hold a ref.
*/
List *ic_proxy_prev_addrs = NIL;
/*
* List<unowned ICProxyAddr *>, the classified addresses lists.
*
* - if an address is removed from the GUC gp_interconnect_proxy_addresses,
* it is put in the "removed" list;
* - if an address is newly added to the GUC, it is in the "added" list;
* - if an address is updated, it is in both the "removed" and "added" lists;
*
* The addresses of these lists must not be freed, they are actually held by
* ic_proxy_addrs or ic_proxy_prev_addrs.
*/
List *ic_proxy_removed_addrs = NIL;
List *ic_proxy_added_addrs = NIL;
/*
* List<ICProxyAddr *>, the addresses list that are being resolved.
*/
......@@ -42,6 +64,87 @@ static List *ic_proxy_unknown_addrs = NIL;
*/
static ICProxyAddr *ic_proxy_my_addr = NULL;
static int
ic_proxy_addr_compare_dbid(const void *a, const void *b, void *arg)
{
const ICProxyAddr *addr1 = a;
const ICProxyAddr *addr2 = b;
return addr1->dbid - addr2->dbid;
}
/*
* Classify the addrs as added, deleted, updated and unchanged.
*
* Both the old and new lists must be sorted by dbid, the caller is responsible
* to ensure this.
*/
static void
ic_proxy_classify_addresses(List *oldaddrs, List *newaddrs)
{
ListCell *lcold;
ListCell *lcnew;
ic_proxy_added_addrs = ic_proxy_list_free(ic_proxy_added_addrs);
ic_proxy_removed_addrs = ic_proxy_list_free(ic_proxy_removed_addrs);
lcold = list_head(oldaddrs);
lcnew = list_head(newaddrs);
while (lcold && lcnew)
{
ICProxyAddr *old = lfirst(lcold);
ICProxyAddr *new = lfirst(lcnew);
if (old->dbid < new->dbid)
{
/* the address is removed */
ic_proxy_removed_addrs = lappend(ic_proxy_removed_addrs, old);
lcold = lnext(lcold);
}
else if (old->dbid > new->dbid)
{
/* the address is newly added */
ic_proxy_added_addrs = lappend(ic_proxy_added_addrs, new);
lcnew = lnext(lcnew);
}
/*
* note that the new->sockaddr is not filled yet, so we must compare
* with the hostname and service as strings.
*/
else if (strcmp(old->service, new->service) ||
strcmp(old->hostname, new->hostname))
{
/* the address is updated */
ic_proxy_removed_addrs = lappend(ic_proxy_removed_addrs, old);
ic_proxy_added_addrs = lappend(ic_proxy_added_addrs, new);
lcold = lnext(lcold);
lcnew = lnext(lcnew);
}
else
{
/* the address is unchanged */
lcold = lnext(lcold);
lcnew = lnext(lcnew);
}
}
/* all the addresses remaining in the old list are removed */
for ( ; lcold; lcold = lnext(lcold))
{
ICProxyAddr *old = lfirst(lcold);
ic_proxy_removed_addrs = lappend(ic_proxy_removed_addrs, old);
}
/* all the addresses remaining in the new list are newly added */
for ( ; lcnew; lcnew = lnext(lcnew))
{
ICProxyAddr *new = lfirst(lcnew);
ic_proxy_added_addrs = lappend(ic_proxy_added_addrs, new);
}
}
/*
* Resolved one address.
*/
......@@ -122,18 +225,13 @@ ic_proxy_addr_on_getaddrinfo(uv_getaddrinfo_t *req,
void
ic_proxy_reload_addresses(uv_loop_t *loop)
{
/* reset the old addresses */
{
ListCell *cell;
foreach(cell, ic_proxy_addrs)
{
ic_proxy_free(lfirst(cell));
}
list_free(ic_proxy_addrs);
ic_proxy_addrs = NIL;
}
/*
* save the old addresses to the "prev" list, it is used to know the diffs
* of the addresses.
*/
ic_proxy_prev_addrs = ic_proxy_list_free_deep(ic_proxy_prev_addrs);
ic_proxy_prev_addrs = ic_proxy_addrs;
ic_proxy_addrs = NULL;
/* cancel any unfinished getaddrinfo reqs */
{
......@@ -203,6 +301,14 @@ ic_proxy_reload_addresses(uv_loop_t *loop)
fclose(f);
ic_proxy_free(buf);
}
/* sort the new addrs so it's easy to diff */
ic_proxy_unknown_addrs = list_qsort(ic_proxy_unknown_addrs,
ic_proxy_addr_compare_dbid, NULL);
/* the last thing is to classify the addrs */
ic_proxy_classify_addresses(ic_proxy_prev_addrs /* oldaddrs */,
ic_proxy_unknown_addrs /* newaddrs */);
}
/*
......
......@@ -43,6 +43,13 @@ struct ICProxyAddr
* List<ICProxyAddr *>
*/
extern List *ic_proxy_addrs;
extern List *ic_proxy_prev_addrs;
/*
* List<unowned ICProxyAddr *>
*/
extern List *ic_proxy_removed_addrs;
extern List *ic_proxy_added_addrs;
extern void ic_proxy_reload_addresses(uv_loop_t *loop);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册