From 19f1c2b4ac12a025235f52510bbd5d2a753aa8e9 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 4 Oct 2008 00:07:28 +0200 Subject: [PATCH] And the files that actually handler the tender phase now. --- handler_virt_tender.c | 208 ++++++++++++++++++++++++++++++++++++++++++++++++++ handler_virt_tender.h | 1 + 2 files changed, 209 insertions(+) create mode 100644 handler_virt_tender.c create mode 100644 handler_virt_tender.h diff --git a/handler_virt_tender.c b/handler_virt_tender.c new file mode 100644 index 0000000..7a6e44a --- /dev/null +++ b/handler_virt_tender.c @@ -0,0 +1,208 @@ +#include "handler_virt.h" +#include "handler_clusterstats.h" +#include "handler_virt_tender.h" +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +static void entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, AVAHI_GCC_UNUSED void *userdata) { + switch (state) { + case AVAHI_ENTRY_GROUP_ESTABLISHED : + /* The entry group has been established successfully */ + break; + + case AVAHI_ENTRY_GROUP_COLLISION : { + /* A service name collision with a remote service + * happened. */ + break; + } + + case AVAHI_ENTRY_GROUP_FAILURE : + /* Some kind of failure happened while we were registering our services */ + break; + + case AVAHI_ENTRY_GROUP_UNCOMMITED: + case AVAHI_ENTRY_GROUP_REGISTERING: + ; + } +} + +static void tender_resolve_callback( + AvahiServiceResolver *r, + AVAHI_GCC_UNUSED AvahiIfIndex interface, + AVAHI_GCC_UNUSED AvahiProtocol protocol, + AvahiResolverEvent event, + const char *name, + const char *type, + const char *domain, + const char *host_name, + const AvahiAddress *address, + uint16_t port, + AvahiStringList *txt, + AvahiLookupResultFlags flags, + void* userdata) { + + tender_t *tender = userdata; + + assert(r); + + /* Called whenever a service has been resolved successfully or timed out */ + + switch (event) { + case AVAHI_RESOLVER_FAILURE: + // fprintf(stderr, "(Resolver) FAILURE!\n"); + avahi_service_resolver_free(r); + break; + + case AVAHI_RESOLVER_FOUND: { + char a[AVAHI_ADDRESS_STR_MAX], *t; + AvahiStringList *needle; + +// fprintf(stderr, "(Resolver) Service '%s' of type '%s' in domain '%s':\n", name, type, domain); + + avahi_address_snprint(a, sizeof(a), address); + t = avahi_string_list_to_string(txt); +/* fprintf(stderr, + "\t%s:%u (%s)\n" + "\tTXT=%s\n" + "\tcookie is %u\n" + "\tis_local: %i\n" + "\tour_own: %i\n" + "\twide_area: %i\n" + "\tmulticast: %i\n" + "\tcached: %i\n", + host_name, port, a, + t, + avahi_string_list_get_service_cookie(txt), + !!(flags & AVAHI_LOOKUP_RESULT_LOCAL), + !!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN), + !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA), + !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST), + !!(flags & AVAHI_LOOKUP_RESULT_CACHED));*/ + + + avahi_free(t); + + if (tender->name) { + unsigned int len = strlen(tender->name); + if (strlen(name) > len && name[len] == '.' && strncmp(tender->name, name, len) == 0) { + if ((needle = avahi_string_list_find (txt, "cost")) != NULL) { + + float amount; + char *cost; + avahi_string_list_get_pair (needle, NULL, &cost, NULL); + amount = atof(cost); + + TRACE("tender", "%s will run %s for the cost of L$W %f\n", host_name, tender->name, amount); + if (amount < tender->cost) { + /* TODO: LOCK */ + tender->cost = amount; + tender->dom = strdup(host_name); + TRACE("tender", "We will consider his offer!"); + } + + avahi_free(cost); + } + } + } + break; + } + } +} + +static void tender_browse_callback( + AvahiServiceBrowser *b, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char *name, + const char *type, + const char *domain, + AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, + void* userdata) { + AvahiClient *c; + assert(b); + + c = avahi_service_browser_get_client(b); + + /* Called whenever a new services becomes available on the LAN or is removed from the LAN */ + + switch (event) { + case AVAHI_BROWSER_FAILURE: + fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_client_errno(c))); + return; + + case AVAHI_BROWSER_NEW: + fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain); + + /* We ignore the returned resolver object. In the callback + function we free it. If the server is terminated before + the callback function is called the server will free + the resolver for us. */ + + if (!(avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, tender_resolve_callback, userdata))) + fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c))); + + break; + + case AVAHI_BROWSER_REMOVE: + fprintf(stderr, "%s, (Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", __func__, name, type, domain); + break; + + case AVAHI_BROWSER_ALL_FOR_NOW: + case AVAHI_BROWSER_CACHE_EXHAUSTED: + fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW"); + break; + } +} + +char * create_tender(cherokee_handler_virt_t *hdl, const char *name, unsigned long memory) { + char txt[255]; + tender_t best_tender; + + snprintf(txt, 253, "memory=%lu", memory); + txt[254] = '\0'; + + best_tender.name = name; + best_tender.cost = FLT_MAX; + best_tender.dom = NULL; + + avahi_threaded_poll_lock(HDL_CLUSTERSTATS_PROPS(hdl)->threaded_poll); + AvahiServiceBrowser *sb = avahi_service_browser_new(HDL_CLUSTERSTATS_PROPS(hdl)->client, AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, "_tender._tcp", + NULL, 0, tender_browse_callback, &best_tender); + + if (sb == NULL) { + TRACE("avahi", "For whatever reason the sb is NULL\n"); + } else { + AvahiEntryGroup *group = avahi_entry_group_new(HDL_CLUSTERSTATS_PROPS(hdl)->client, entry_group_callback, NULL); + + if (group == NULL) { + TRACE("avahi", "For whatever reason the group is NULL\n"); + } else { + avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, + best_tender.name, "_offer._tcp", NULL, NULL, 651, txt, NULL, NULL); + avahi_entry_group_commit(group); + avahi_threaded_poll_unlock(HDL_CLUSTERSTATS_PROPS(hdl)->threaded_poll); + + sleep(3); /* we are for quick bidding ;) */ + + avahi_threaded_poll_lock(HDL_CLUSTERSTATS_PROPS(hdl)->threaded_poll); + avahi_entry_group_free(group); + } + + avahi_service_browser_free(sb); + } + avahi_threaded_poll_unlock(HDL_CLUSTERSTATS_PROPS(hdl)->threaded_poll); + + return best_tender.dom; +} diff --git a/handler_virt_tender.h b/handler_virt_tender.h new file mode 100644 index 0000000..0d9355e --- /dev/null +++ b/handler_virt_tender.h @@ -0,0 +1 @@ +char * create_tender(cherokee_handler_virt_t *hdl, const char *name, unsigned long memory); -- 2.11.4.GIT