changeset 1042:dcc0eff204cf

Add extension that balances load over multiple peers based on outstanding requests.
author Thomas Klausner <tk@giga.or.at>
date Thu, 18 Apr 2013 15:50:10 +0200
parents a740267f1be6
children 3fa4dc91adee
files extensions/rt_load_balance/CMakeLists.txt extensions/rt_load_balance/rt_load_balance.c
diffstat 2 files changed, 81 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/rt_load_balance/CMakeLists.txt	Thu Apr 18 15:50:10 2013 +0200
@@ -0,0 +1,20 @@
+# The rt_load_balance extension
+PROJECT("Routing extension splits requests evenly over multiple hosts, using current load as routing indicator" C)
+
+# List of source files
+SET(RT_IGNORE_DH_SRC
+	rt_load_balance.c
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+# Compile these files as a freeDiameter extension
+FD_ADD_EXTENSION(rt_load_balance ${RT_IGNORE_DH_SRC})
+
+####
+## INSTALL section ##
+
+# We install with the daemon component because it is a base feature.
+INSTALL(TARGETS rt_load_balance
+	LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+	COMPONENT freeDiameter-daemon)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/rt_load_balance/rt_load_balance.c	Thu Apr 18 15:50:10 2013 +0200
@@ -0,0 +1,61 @@
+#include <freeDiameter/extension.h>
+
+/* 
+ * Load balancing extension. Send request to least-loaded node.
+ */
+
+/* The callback for load balancing the requests across the peers */
+static int rt_load_balancing(void * cbdata, struct msg * msg, struct fd_list * candidates)
+{
+	struct fd_list *lic;
+	
+	TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
+	
+	CHECK_PARAMS(msg && candidates);
+	
+	/* Check if it is worth processing the message */
+	if (FD_IS_LIST_EMPTY(candidates))
+		return 0;
+
+	/* load balancing */
+	for (lic = candidates->next; lic != candidates; lic = lic->next) {
+		struct rtd_candidate * cand = (struct rtd_candidate *) lic;
+		struct peer_hdr *peer;
+		long to_receive, to_send, load;
+		int score;
+		CHECK_FCT(fd_peer_getbyid(cand->diamid, cand->diamidlen, 0, &peer));
+		CHECK_FCT(fd_peer_get_load_pending(peer, &to_receive, &to_send));
+                load = to_receive + to_send;
+		score = cand->score;
+		if (load > 5)
+			cand->score -= 5;
+		else
+			cand->score -= load;
+		TRACE_DEBUG(INFO, "evaluated peer `%.*s', score was %d, now %d", (int)cand->diamidlen, cand->diamid, score, cand->score);
+	}
+
+	return 0;
+}
+
+/* handler */
+static struct fd_rt_out_hdl * rt_load_balancing_hdl = NULL;
+
+/* entry point */
+static int rt_load_balance_entry(char * conffile)
+{
+	/* Register the callback */
+	CHECK_FCT(fd_rt_out_register(rt_load_balancing, NULL, 10, &rt_load_balancing_hdl));
+
+	TRACE_DEBUG(INFO, "Extension 'Load Balancing' initialized");
+	return 0;
+}
+
+/* Unload */
+void fd_ext_fini(void)
+{
+	/* Unregister the callbacks */
+	CHECK_FCT_DO(fd_rt_out_unregister(rt_load_balancing_hdl, NULL), /* continue */);
+	return ;
+}
+
+EXTENSION_ENTRY("rt_load_balance", rt_load_balance_entry);
"Welcome to our mercurial repository"