static void procResult(cache_waiting_t *ptr, rq_blacklist_status_t status) { struct timeval tv; cache_entry_t *entry; // will need to remove the 'waiting' object from the list... which means // that the waiting object will need a pointer to the control structure. assert(ptr); assert(ptr->blacklist); assert(ptr->blacklist->waiting); ll_remove(ptr->blacklist->waiting, ptr); assert(ptr->ip != 0); // we need to make an entry in the cache for this entry... entry = (cache_entry_t *) malloc(sizeof(cache_entry_t)); entry->ip = ptr->ip; entry->status = status; // determine the expiry. assert(ptr->blacklist->expires > 0); gettimeofday(&tv, NULL); entry->expires = tv.tv_sec + ptr->blacklist->expires; // place it at the top. assert(ptr->blacklist->cache); ll_push_head(ptr->blacklist->cache, entry); // call the handler that was saved. assert(ptr->handler); ptr->handler(status, ptr->arg); }
static void acc (struct statistic *s, const struct ccase *cx, double c UNUSED, double cc UNUSED, double y) { struct box_whisker *bw = UP_CAST (s, struct box_whisker, parent.parent); bool extreme; struct outlier *o; if ( y > bw->hinges[2] + bw->step) /* Upper outlier */ { extreme = (y > bw->hinges[2] + 2 * bw->step) ; } else if (y < bw->hinges[0] - bw->step) /* Lower outlier */ { extreme = (y < bw->hinges[0] - 2 * bw->step) ; } else /* Not an outlier */ { if (bw->whiskers[0] == SYSMIS) bw->whiskers[0] = y; if (y > bw->whiskers[1]) bw->whiskers[1] = y; return; } /* y is an outlier */ o = xzalloc (sizeof *o) ; o->value = y; o->extreme = extreme; ds_init_empty (&o->label); if (bw->id_var) { char *s = data_out (case_data_idx (cx, bw->id_idx), var_get_encoding (bw->id_var), var_get_print_format (bw->id_var)); ds_put_cstr (&o->label, s); free (s); } else { ds_put_format (&o->label, "%ld", (casenumber) case_data_idx (cx, bw->id_idx)->f); } ll_push_head (&bw->outliers, &o->ll); }
//----------------------------------------------------------------------------- // This callback function is used when a complete message is received to // consume. We basically need to create a request to handle it, add it to the // list. If a reply is sent during the processing, then it will close out the // request automatically, otherwise it will be up to something else to close it // out. static void message_handler(rq_message_t *msg, void *arg) { int processed; rq_http_t *http; rq_http_req_t *req; assert(msg); assert(arg); http = (rq_http_t *) arg; assert(http); // We dont know what the use of this object will be, so we need to create it // and put it in a list (to keep track of it) until something gets rid of it. req = req_new(http, http->arg); req->msg = msg; assert(req->reply); assert(BUF_LENGTH(req->reply) == 0); assert(msg->data); assert(http->risp); processed = risp_process(http->risp, req, BUF_LENGTH(msg->data), BUF_DATA(msg->data)); assert(processed == BUF_LENGTH(msg->data)); // if we still have the msg pointer as part of the request, then the message // hasn't been replied yet, so we need to add the request to the list and // let it finish elsewhere. if (req->msg) { assert(req->inprocess == 0); req->inprocess++; // then we need to add this request to the list. assert(http->req_list); ll_push_head(http->req_list, req); req = NULL; } else { // We have already replied to the request, so we dont need it anymore. req_free(req); req = NULL; } }
//----------------------------------------------------------------------------- // callback function that will fire when the connection to the controller is reached. static void controller_connect_handler(int fd, short int flags, void *arg) { controller_t *ct = (controller_t *) arg; node_t *node; system_data_t *sysdata; queue_t *q; int error; socklen_t foo; struct timeval t = {.tv_sec = 1, .tv_usec = 0}; short int exclusive; assert(fd >= 0); assert(flags != 0); assert(ct); assert(ct->node == NULL); assert(ct->target); assert(ct->sysdata); sysdata = ct->sysdata; // we only need to detect EV_WRITE for a connect event. assert(flags == EV_WRITE); // remove the connect event assert(ct->connect_event); event_free(ct->connect_event); ct->connect_event = NULL; // we are no longer connected. We are either connected, or not. assert(BIT_TEST(ct->flags, FLAG_CONTROLLER_CONNECTING)); BIT_CLEAR(ct->flags, FLAG_CONTROLLER_CONNECTING); // check to see if we really are connected. foo = sizeof(error); getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &foo); if (error == ECONNREFUSED) { // we were connecting, but couldn't. BIT_SET(ct->flags, FLAG_CONTROLLER_CLOSED); // close the socket that didn't connect. close(fd); //set the action so that we can attempt to reconnect. assert(ct->connect_event == NULL); assert(sysdata->evbase); ct->connect_event = evtimer_new(sysdata->evbase, controller_wait_handler, (void *) ct); evtimer_add(ct->connect_event, &t); } else { logger(((system_data_t *)ct->sysdata)->logging, 2, "connected to remote controller: %s", ct->target); // create the node object. node = node_create(sysdata, fd); // add node to the main nodes list. ct->node = node; assert(node->controller == NULL); node->controller = ct; BIT_SET(node->flags, FLAG_NODE_CONTROLLER); // we need to check to see if we have any queues with active consumers, // and if we do, then we need to send consume requests to this node for // each one. assert(sysdata->queues); ll_start(sysdata->queues); while ((q = ll_next(sysdata->queues))) { assert(q->qid > 0); assert(q->name); if (ll_count(&q->nodes_busy) > 0 || ll_count(&q->nodes_ready) > 0) { logger(((system_data_t *)ct->sysdata)->logging, 2, "Sending queue consume ('%s') to alternate controller at %s", q->name, ct->target ); exclusive = 0; if (BIT_TEST(q->flags, QUEUE_FLAG_EXCLUSIVE)) exclusive = 1; sendConsume(node, q->name, 1, RQ_PRIORITY_LOW, exclusive); ll_push_head(&q->nodes_consuming, node); } } ll_finish(sysdata->queues); } } void controller_connect(controller_t *ct) { evutil_socket_t sock; int result; int len; assert(ct); assert(ct->target); assert(ct->node == NULL); assert(BIT_TEST(ct->flags, FLAG_CONTROLLER_CONNECTED) == 0); assert(BIT_TEST(ct->flags, FLAG_CONTROLLER_FAILED) == 0); assert(BIT_TEST(ct->flags, FLAG_CONTROLLER_CONNECTING) == 0); // if not already resolved.... resolve the target. if (BIT_TEST(ct->flags, FLAG_CONTROLLER_RESOLVED) == 0) { assert(ct->flags == 0); logger(((system_data_t *)ct->sysdata)->logging, 3, "resolving controller %s.", ct->target); len = sizeof(ct->saddr); if (evutil_parse_sockaddr_port(ct->target, &ct->saddr, &len) == 0) { BIT_SET(ct->flags, FLAG_CONTROLLER_RESOLVED); } else { BIT_SET(ct->flags, FLAG_CONTROLLER_FAILED); } } if (BIT_TEST(ct->flags, FLAG_CONTROLLER_FAILED) == 0) { assert(BIT_TEST(ct->flags, FLAG_CONTROLLER_RESOLVED)); BIT_SET(ct->flags, FLAG_CONTROLLER_CONNECTING); sock = socket(AF_INET,SOCK_STREAM,0); assert(sock >= 0); // Before we attempt to connect, set the socket to non-blocking mode. evutil_make_socket_nonblocking(sock); logger(((system_data_t *)ct->sysdata)->logging, 3, "Attempting Remote connect to %s.", ct->target); result = connect(sock, &ct->saddr, sizeof(struct sockaddr)); assert(result < 0); assert(errno == EINPROGRESS); // connect process has been started. Now we need to create an event so that we know when the connect has completed. assert(ct->connect_event == NULL); assert(ct->sysdata); assert(((system_data_t *)ct->sysdata)->evbase); ct->connect_event = event_new(((system_data_t *)ct->sysdata)->evbase, sock, EV_WRITE, controller_connect_handler, ct); event_add(ct->connect_event, NULL); } else { assert(ct->target); logger(((system_data_t *)ct->sysdata)->logging, 2, "Remote connect to %s has failed.", ct->target); } }