7a6e44ab6f9c3789c64176361daac426b9bf7a70
[handlervirt.git] / handler_virt_tender.c
blob7a6e44ab6f9c3789c64176361daac426b9bf7a70
1 #include "handler_virt.h"
2 #include "handler_clusterstats.h"
3 #include "handler_virt_tender.h"
4 #include <cherokee/cherokee.h>
5 #include <float.h>
7 #include <avahi-client/client.h>
8 #include <avahi-client/publish.h>
9 #include <avahi-client/lookup.h>
11 #include <avahi-common/alternative.h>
12 #include <avahi-common/simple-watch.h>
13 #include <avahi-common/malloc.h>
14 #include <avahi-common/error.h>
15 #include <avahi-common/timeval.h>
17 static void entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, AVAHI_GCC_UNUSED void *userdata) {
18 switch (state) {
19 case AVAHI_ENTRY_GROUP_ESTABLISHED :
20 /* The entry group has been established successfully */
21 break;
23 case AVAHI_ENTRY_GROUP_COLLISION : {
24 /* A service name collision with a remote service
25 * happened. */
26 break;
29 case AVAHI_ENTRY_GROUP_FAILURE :
30 /* Some kind of failure happened while we were registering our services */
31 break;
33 case AVAHI_ENTRY_GROUP_UNCOMMITED:
34 case AVAHI_ENTRY_GROUP_REGISTERING:
39 static void tender_resolve_callback(
40 AvahiServiceResolver *r,
41 AVAHI_GCC_UNUSED AvahiIfIndex interface,
42 AVAHI_GCC_UNUSED AvahiProtocol protocol,
43 AvahiResolverEvent event,
44 const char *name,
45 const char *type,
46 const char *domain,
47 const char *host_name,
48 const AvahiAddress *address,
49 uint16_t port,
50 AvahiStringList *txt,
51 AvahiLookupResultFlags flags,
52 void* userdata) {
54 tender_t *tender = userdata;
56 assert(r);
58 /* Called whenever a service has been resolved successfully or timed out */
60 switch (event) {
61 case AVAHI_RESOLVER_FAILURE:
62 // fprintf(stderr, "(Resolver) FAILURE!\n");
63 avahi_service_resolver_free(r);
64 break;
66 case AVAHI_RESOLVER_FOUND: {
67 char a[AVAHI_ADDRESS_STR_MAX], *t;
68 AvahiStringList *needle;
70 // fprintf(stderr, "(Resolver) Service '%s' of type '%s' in domain '%s':\n", name, type, domain);
72 avahi_address_snprint(a, sizeof(a), address);
73 t = avahi_string_list_to_string(txt);
74 /* fprintf(stderr,
75 "\t%s:%u (%s)\n"
76 "\tTXT=%s\n"
77 "\tcookie is %u\n"
78 "\tis_local: %i\n"
79 "\tour_own: %i\n"
80 "\twide_area: %i\n"
81 "\tmulticast: %i\n"
82 "\tcached: %i\n",
83 host_name, port, a,
85 avahi_string_list_get_service_cookie(txt),
86 !!(flags & AVAHI_LOOKUP_RESULT_LOCAL),
87 !!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN),
88 !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA),
89 !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST),
90 !!(flags & AVAHI_LOOKUP_RESULT_CACHED));*/
93 avahi_free(t);
95 if (tender->name) {
96 unsigned int len = strlen(tender->name);
97 if (strlen(name) > len && name[len] == '.' && strncmp(tender->name, name, len) == 0) {
98 if ((needle = avahi_string_list_find (txt, "cost")) != NULL) {
100 float amount;
101 char *cost;
102 avahi_string_list_get_pair (needle, NULL, &cost, NULL);
103 amount = atof(cost);
105 TRACE("tender", "%s will run %s for the cost of L$W %f\n", host_name, tender->name, amount);
106 if (amount < tender->cost) {
107 /* TODO: LOCK */
108 tender->cost = amount;
109 tender->dom = strdup(host_name);
110 TRACE("tender", "We will consider his offer!");
113 avahi_free(cost);
117 break;
122 static void tender_browse_callback(
123 AvahiServiceBrowser *b,
124 AvahiIfIndex interface,
125 AvahiProtocol protocol,
126 AvahiBrowserEvent event,
127 const char *name,
128 const char *type,
129 const char *domain,
130 AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
131 void* userdata) {
132 AvahiClient *c;
133 assert(b);
135 c = avahi_service_browser_get_client(b);
137 /* Called whenever a new services becomes available on the LAN or is removed from the LAN */
139 switch (event) {
140 case AVAHI_BROWSER_FAILURE:
141 fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_client_errno(c)));
142 return;
144 case AVAHI_BROWSER_NEW:
145 fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
147 /* We ignore the returned resolver object. In the callback
148 function we free it. If the server is terminated before
149 the callback function is called the server will free
150 the resolver for us. */
152 if (!(avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, tender_resolve_callback, userdata)))
153 fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c)));
155 break;
157 case AVAHI_BROWSER_REMOVE:
158 fprintf(stderr, "%s, (Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", __func__, name, type, domain);
159 break;
161 case AVAHI_BROWSER_ALL_FOR_NOW:
162 case AVAHI_BROWSER_CACHE_EXHAUSTED:
163 fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW");
164 break;
168 char * create_tender(cherokee_handler_virt_t *hdl, const char *name, unsigned long memory) {
169 char txt[255];
170 tender_t best_tender;
172 snprintf(txt, 253, "memory=%lu", memory);
173 txt[254] = '\0';
175 best_tender.name = name;
176 best_tender.cost = FLT_MAX;
177 best_tender.dom = NULL;
179 avahi_threaded_poll_lock(HDL_CLUSTERSTATS_PROPS(hdl)->threaded_poll);
180 AvahiServiceBrowser *sb = avahi_service_browser_new(HDL_CLUSTERSTATS_PROPS(hdl)->client, AVAHI_IF_UNSPEC,
181 AVAHI_PROTO_UNSPEC, "_tender._tcp",
182 NULL, 0, tender_browse_callback, &best_tender);
184 if (sb == NULL) {
185 TRACE("avahi", "For whatever reason the sb is NULL\n");
186 } else {
187 AvahiEntryGroup *group = avahi_entry_group_new(HDL_CLUSTERSTATS_PROPS(hdl)->client, entry_group_callback, NULL);
189 if (group == NULL) {
190 TRACE("avahi", "For whatever reason the group is NULL\n");
191 } else {
192 avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0,
193 best_tender.name, "_offer._tcp", NULL, NULL, 651, txt, NULL, NULL);
194 avahi_entry_group_commit(group);
195 avahi_threaded_poll_unlock(HDL_CLUSTERSTATS_PROPS(hdl)->threaded_poll);
197 sleep(3); /* we are for quick bidding ;) */
199 avahi_threaded_poll_lock(HDL_CLUSTERSTATS_PROPS(hdl)->threaded_poll);
200 avahi_entry_group_free(group);
203 avahi_service_browser_free(sb);
205 avahi_threaded_poll_unlock(HDL_CLUSTERSTATS_PROPS(hdl)->threaded_poll);
207 return best_tender.dom;