Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
//-----------------------------------------------------------------------------
// 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;
	}
}
Ejemplo n.º 4
0
//-----------------------------------------------------------------------------
// 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);
	}
}