Esempio n. 1
0
int main(int argc, char **argv) {
  hrtime_t s0, s, f, f0;
  uint64_t cnt = 0, icnt = 0;
  int psize = 0, i = 0;
  fq_client c;
  fq_msg *m;
  char *fq_debug = getenv("FQ_DEBUG");
  if(fq_debug) fq_debug_set_bits(atoi(fq_debug));
  signal(SIGPIPE, SIG_IGN);
  fq_client_init(&c, 0, logger);
  if(argc < 5) {
    fprintf(stderr, "%s <host> <port> <user> <pass> [size [count]]\n",
            argv[0]);
    exit(-1);
  }
  fq_client_creds(c, argv[1], atoi(argv[2]), argv[3], argv[4]);
  fq_client_heartbeat(c, 1000);
  fq_client_set_backlog(c, 10000, 100);
  fq_client_connect(c);

  if(argc > 5) {
     psize = atoi(argv[5]);
  }
  printf("payload size -> %d\n", psize);
  if(argc > 6) {
    send_count = atoi(argv[6]);
  }
  printf("message count -> %d\n", send_count);

  s0 = s = fq_gethrtime();
  while(i < send_count || fq_client_data_backlog(c) > 0) {
    if(i < send_count) {
      m = fq_msg_alloc_BLANK(psize);
      memset(m->payload, 0, psize);
      fq_msg_exchange(m, "maryland", 8);
      fq_msg_route(m, "test.prefix.boo", 15);
      fq_msg_id(m, NULL);
      fq_client_publish(c, m);
      cnt++;
      i++;
      fq_msg_free(m);
    }
    else usleep(100);


    f = fq_gethrtime();
    if(f-s > 1000000000) {
      print_rate(c, s, f, cnt, icnt);
      icnt = 0;
      cnt = 0;
      s = f;
    }
  }
  f0 = fq_gethrtime();
  print_rate(c, s0, f0, i, 0);
  (void) argc;
  return 0;
}
Esempio n. 2
0
int main(int argc, char **argv) {
  hrtime_t s, f;
  uint64_t cnt = 0, icnt = 0, icnt_total = 0;
  int rcvd = 0;
  fq_client c;
  fq_bind_req breq;
  fq_msg *m;
  signal(SIGPIPE, SIG_IGN);
  fq_client_init(&c, 0, logger);
  if(argc < 5) {
    fprintf(stderr, "%s <host> <port> <user> <pass> [size [count]]\n",
            argv[0]);
    exit(-1);
  }
  fq_client_creds(c, argv[1], atoi(argv[2]), argv[3], argv[4]);
  fq_client_heartbeat(c, 1000);
  fq_client_set_backlog(c, 10000, 100);
  fq_client_connect(c);

  memset(&breq, 0, sizeof(breq));
  memcpy(breq.exchange.name, "maryland", 8);
  breq.exchange.len = 8;
  breq.peermode = 0;
  breq.program = (char *)"prefix:\"test.prefix.\"";

  fq_client_bind(c, &breq);
  while(breq.out__route_id == 0) usleep(100);
  printf("route set -> %u\n", breq.out__route_id);
  if(breq.out__route_id == FQ_BIND_ILLEGAL) {
    fprintf(stderr, "Failure to bind...\n");
    exit(-1);
  }

  s = fq_gethrtime();
  while(1) {
    f = fq_gethrtime();
    while(m = fq_client_receive(c)) {
      icnt++;
      icnt_total++;
      rcvd++;
      fq_msg_deref(m);
    }
    usleep(1000);
    if(f-s > 1000000000) {
      print_rate(c, s, f, cnt, icnt);
      printf("total: %llu\n", (unsigned long long)icnt_total);
      icnt = 0;
      cnt = 0;
      s = f;
    }
  }
  (void) argc;
  return 0;
}
Esempio n. 3
0
static int
fq_socket_connect(fq_conn_s *conn_s) {
  int fd, rv, on = 1;
  /* re-resolve if we've not done so quite recently */
  if(conn_s->last_resolve == 0 ||
     (fq_gethrtime() - conn_s->last_resolve) > MAX_RESOLVE_CACHE) {
    if(fq_resolve_endpoint(conn_s) < 0) {
      return -1;
    }
  }
  fd = socket(AF_INET, SOCK_STREAM, 0);
  if(fd == -1) return -1;
  rv = connect(fd, (struct sockaddr *)&conn_s->remote,
               sizeof(conn_s->remote));
  if(rv == -1) {
    snprintf(conn_s->error, sizeof(conn_s->error),
             "socket: %s", strerror(errno));
    CONNERR_S(conn_s);
    close(fd);
    return -1;
  }
  /* If this fails, we ignore it */
  (void)setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
  return fd;
}
Esempio n. 4
0
File: fq_rcvr.c Progetto: Sphonic/fq
int main(int argc, char **argv) {
  hrtime_t s, f;
  uint64_t cnt = 0, icnt = 0, icnt_total = 0;
  int rcvd = 0;
  fq_client c;
  fq_msg *m;

  char *fq_debug = getenv("FQ_DEBUG");
  if(fq_debug) fq_debug_set_bits(atoi(fq_debug));
  signal(SIGPIPE, SIG_IGN);
  fq_client_init(&c, 0, logger);
  if(fq_client_hooks(c, &hooks)) {
    fprintf(stderr, "Can't register hooks\n");
    exit(-1);
  }
  if(argc < 5) {
    fprintf(stderr, "%s <host> <port> <user> <pass> [size [count]]\n",
            argv[0]);
    exit(-1);
  }
  fq_client_hooks(c, &hooks);
  fq_client_creds(c, argv[1], atoi(argv[2]), argv[3], argv[4]);
  fq_client_heartbeat(c, 1000);
  fq_client_set_backlog(c, 10000, 100);
  fq_client_connect(c);

  s = fq_gethrtime();
  while(1) {
    f = fq_gethrtime();
    while(m = fq_client_receive(c)) {
      icnt++;
      icnt_total++;
      rcvd++;
      fq_msg_deref(m);
    }
    usleep(1000);
    if(f-s > 1000000000) {
      print_rate(c, s, f, cnt, icnt);
      printf("total: %llu\n", (unsigned long long)icnt_total);
      icnt = 0;
      cnt = 0;
      s = f;
    }
  }
  (void) argc;
  return 0;
}
Esempio n. 5
0
static int
fq_resolve_endpoint(fq_conn_s *conn_s) {
  conn_s->remote.sin_family = AF_INET;
  conn_s->remote.sin_port = htons(conn_s->port);
  if(inet_pton(AF_INET, conn_s->host, &conn_s->remote.sin_addr) != 1) {
#ifdef HAVE_GETHOSTBYNAME_R
    struct hostent hostbuf, *hp;
    struct in_addr **addr_list;
    int buflen = 1024, herr;
    char *buf;
    if((buf = malloc(buflen)) == NULL) {
      CONNERR(conn_s, "out of memory");
      return -1;
    }
    while((hp = gethostbyname_r(conn_s->host, &hostbuf, buf, buflen, &herr)) == NULL &&
          errno == ERANGE) {
      buflen *= 2;
      if((buf = realloc(buf, buflen)) == NULL) {
        CONNERR(conn_s, "out of memory");
        free(buf);
        return -1;
      }
    }
    if(!hp) {
      CONNERR(conn_s, "host lookup failed");
      free(buf);
      return -1;
    }
    addr_list = (struct in_addr **)hp->h_addr_list;
    if(*addr_list == 0) {
      CONNERR(conn_s, "no address for host");
      free(buf);
      return -1;
    }
    memcpy(&conn_s->remote.sin_addr, *addr_list, sizeof(struct in_addr));
    free(buf);
#else
    struct hostent *hp;
    struct in_addr **addr_list;
    hp = gethostbyname(conn_s->host);
    if(!hp) {
      CONNERR(conn_s, "host lookup failed");
      return -1;
    }
    addr_list = (struct in_addr **)hp->h_addr_list;
    if(*addr_list == 0) {
      CONNERR(conn_s, "no address for host");
      return -1;
    }
    memcpy(&conn_s->remote.sin_addr, *addr_list, sizeof(struct in_addr));
#endif
  }
  conn_s->last_resolve = fq_gethrtime();
  return 0;
}
Esempio n. 6
0
fq_msg *
fq_msg_alloc_BLANK(size_t s) {
  fq_msg *m;
  m = calloc(offsetof(fq_msg, payload) + ((s | (MSG_ALIGN-1))+1), 1);
  if(!m) return NULL;
  m->payload_len = s;
#ifdef DEBUG
  fq_debug(FQ_DEBUG_MSG, "msg(%p) -> alloc\n", (void *)m);
#endif
  m->arrival_time = fq_gethrtime();
  m->refcnt = 1;
  return m;
}
Esempio n. 7
0
fq_msg *
fq_msg_alloc(const void *data, size_t s) {
  fq_msg *m;
  m = malloc(offsetof(fq_msg, payload) + ((s | (MSG_ALIGN-1))+1));
  if(!m) return NULL;
  memset(m, 0, offsetof(fq_msg, payload));
  m->payload_len = s;
  if(s) memcpy(m->payload, data, s);
#ifdef DEBUG
  fq_debug(FQ_DEBUG_MSG, "msg(%p) -> alloc\n", (void *)m);
#endif
  m->arrival_time = fq_gethrtime();
  m->refcnt = 1;
  return m;
}
Esempio n. 8
0
File: fq_utils.c Progetto: denji/fq
int
fq_debug_fl(const char *file, int line, fq_debug_bits_t b, const char *fmt, ...) {
  int rv;
  va_list argp;
  static hrtime_t epoch = 0;
  hrtime_t now;
  char fmtstring[1024];
  uint64_t p = (uint64_t)pthread_self();
  uint32_t ps = p & 0xffffffff;

  (void)b;
  now = fq_gethrtime();
  if(!epoch) epoch = now;

  snprintf(fmtstring, sizeof(fmtstring), "[%llu] [%08x] %s",
           (now-epoch)/1000, ps, fmt);
  va_start(argp, fmt);
  rv = vfprintf(stderr, fmtstring, argp);
  va_end(argp);
  (void)file;
  (void)line;
  return rv;
}
Esempio n. 9
0
static void
fqd_data_driver(remote_client *parent) {
  remote_data_client *me = parent->data;
  fq_msg *inflight = NULL;
  size_t inflight_sofar = 0;
  buffered_msg_reader *ctx = NULL;
  int had_msgs = 1, flags, needs_write = 1;

  if(((flags = fcntl(me->fd, F_GETFL, 0)) == -1) ||
     (fcntl(me->fd, F_SETFL, flags | O_NONBLOCK) == -1))
    return;

  ctx = fq_buffered_msg_reader_alloc(me->fd, (me->mode == FQ_PROTO_PEER_MODE));
  while(1) {
    uint32_t msgs_in = me->msgs_in, msgs_out = me->msgs_out;
    int rv, timeout_ms = 1000;
    struct pollfd pfd;
    pfd.fd = me->fd;
    pfd.events = POLLIN|POLLHUP;
    if(needs_write) pfd.events |= POLLOUT;
    pfd.revents = 0;
    if(parent->heartbeat_ms && parent->heartbeat_ms < timeout_ms)
      timeout_ms = parent->heartbeat_ms;
    /* if we had msgs, but aren't waiting for write,
     * then we set a very short timeout
     */
    if(had_msgs && !needs_write) timeout_ms = 1;

    rv = poll(&pfd, 1, timeout_ms);
    if(rv < 0) break;

    had_msgs = 0;
    if(rv > 0 && (pfd.revents & POLLIN)) {
      me->last_heartbeat = me->last_activity = fq_gethrtime();
      if(fq_buffered_msg_read(ctx, fqd_dss_read_complete, parent) < 0) {
        fq_debug(FQ_DEBUG_IO, "client read error\n");
        break;
      }
      had_msgs = 1;
    }

    if(!needs_write || (rv > 0 && (pfd.revents & POLLOUT))) {
      fq_msg *m;
      needs_write = 0;
     haveanother:
      m = inflight ? inflight
                   : parent->queue ? fqd_queue_dequeue(parent->queue)
                                   : NULL;

      /* If we're in peer mode, we can just toss messages the remote has seen */
      if(m && me->mode == FQ_PROTO_PEER_MODE &&
         fq_find_in_hops(me->peer_id, m) >= 0) {
        fq_msg_deref(m);
        goto haveanother;
      }

      inflight = NULL;
      while(m) {
        int written;
        size_t octets_out = 0;
        had_msgs = 1;
        written = fq_client_write_msg(me->fd, 1, m, inflight_sofar, &octets_out);
        if(written > 0) inflight_sofar += written;
        if(octets_out) me->octets_out += octets_out;

        if(written > 0 || (written < 0 && errno == EAGAIN)) {
          inflight = m;
          needs_write = 1;
          break;
        }
        else if(written < 0) {
          fq_debug(FQ_DEBUG_IO, "client write error\n");
          goto broken;
        }

        if(FQ_MESSAGE_DELIVER_ENABLED()) {
          fq_dtrace_msg_t dmsg;
          fq_dtrace_remote_client_t dpc;
          fq_dtrace_remote_data_client_t dme;
          DTRACE_PACK_MSG(&dmsg, m);
          DTRACE_PACK_CLIENT(&dpc, parent);
          DTRACE_PACK_DATA_CLIENT(&dme, me);
          FQ_MESSAGE_DELIVER(&dpc, &dme, &dmsg);
        }
        fq_msg_deref(m);
        me->msgs_out++;
        inflight_sofar = 0;
        m = parent->queue ? fqd_queue_dequeue(parent->queue) : NULL;
      }
    }

    if(me->msgs_in != msgs_in || me->msgs_out != msgs_out)
      fq_debug(FQ_DEBUG_MSG, "Round.... %d in, %d out\n", me->msgs_in, me->msgs_out);
  }
broken:
  if(inflight) {
    /* We're screwed here... we might have delivered it. so just toss it */
    fq_msg_deref(inflight);
  }
  if(ctx) fq_buffered_msg_reader_free(ctx);
  parent->data = NULL;
  fq_debug(FQ_DEBUG_IO, "data path from client ended: %s\n", parent->pretty);
}
Esempio n. 10
0
static void *
fq_conn_worker(void *u) {
  int backoff = 0, i;
  bool zero;
  fq_conn_s *conn_s = (fq_conn_s *)u;
  cmd_instr *last_entries[MAX_PENDING] = { NULL };
  int last_entry_idx = 0;
  int next_entry_idx = 0;

#define SAVE_ENTRY(e) do { \
  if(last_entries[next_entry_idx] != NULL) { \
    CONNERR(conn_s, "exceed max cmd pipeline"); \
    goto restart; \
  } \
  last_entries[next_entry_idx++] = e; \
  next_entry_idx = next_entry_idx % MAX_PENDING; \
} while(0)
#define last_entry last_entries[last_entry_idx]
#define PROCESS_ENTRY(e, should_free) do { \
  fq_assert(last_entries[last_entry_idx] == e); \
  if(should_free) free(last_entries[last_entry_idx]); \
  last_entries[last_entry_idx++] = NULL; \
  last_entry_idx = last_entry_idx % MAX_PENDING; \
} while(0)

  cmd_instr *entry;

  ck_pr_inc_uint(&conn_s->thrcnt);

  while(conn_s->stop == 0) {
    int wait_ms = 50;
    if(fq_client_connect_internal(conn_s) == 0) {
      backoff = 0; /* we're good, restart our backoff */
    }
    while(conn_s->data_ready && conn_s->stop == 0) {
      hrtime_t t;
      unsigned long long hb_us;
      struct timeval tv;
      int rv;

      ck_fifo_spsc_dequeue_lock(&conn_s->cmdq);
      while(ck_fifo_spsc_dequeue(&conn_s->cmdq, &entry) == true) {
#ifdef DEBUG
        fq_debug(FQ_DEBUG_CONN, "client acting on user req 0x%04x\n", entry->cmd);
#endif
        switch(entry->cmd) {
          case FQ_PROTO_STATUSREQ:
            fq_debug(FQ_DEBUG_CONN, "sending status request\n");
            if(fq_write_uint16(conn_s->cmd_fd, entry->cmd)) {
              free(entry);
              CONNERR(conn_s, "write failed (statusreq)");
              goto restart;
            }
            SAVE_ENTRY(entry);
            break;
          case FQ_PROTO_HBREQ:
            fq_debug(FQ_DEBUG_CONN, "sending heartbeat request\n");
            if(fq_write_uint16(conn_s->cmd_fd, entry->cmd) ||
               fq_write_uint16(conn_s->cmd_fd, entry->data.heartbeat.ms)) {
              free(entry);
              CONNERR(conn_s, "write failed (hbreq)");
              goto restart;
            }
            conn_s->cmd_hb_ms = entry->data.heartbeat.ms;
            tv.tv_sec = (unsigned long)entry->data.heartbeat.ms / 1000;
            tv.tv_usec = 1000UL * (entry->data.heartbeat.ms % 1000);
            if(setsockopt(conn_s->cmd_fd, SOL_SOCKET, SO_RCVTIMEO,
                          &tv, sizeof(tv)))
              CONNERR(conn_s, strerror(errno));
            tv.tv_sec = (unsigned long)entry->data.heartbeat.ms / 1000;
            tv.tv_usec = 1000UL * (entry->data.heartbeat.ms % 1000);
            if(setsockopt(conn_s->cmd_fd, SOL_SOCKET, SO_SNDTIMEO,
                          &tv, sizeof(tv)))
              CONNERR(conn_s, strerror(errno));
            conn_s->cmd_hb_last = fq_gethrtime();
            free(entry);
            break;
          case FQ_PROTO_BINDREQ:
            {
              unsigned short flags = entry->data.bind->flags;
              if(fq_write_uint16(conn_s->cmd_fd, entry->cmd) ||
                 fq_write_uint16(conn_s->cmd_fd, flags) ||
                 fq_write_short_cmd(conn_s->cmd_fd,
                                    entry->data.bind->exchange.len,
                                    entry->data.bind->exchange.name) < 0 ||
                 fq_write_short_cmd(conn_s->cmd_fd,
                                    strlen(entry->data.bind->program),
                                    entry->data.bind->program) < 0) {
	CONNERR(conn_s, "write failed (bindreq)");
                goto restart;
              }
              SAVE_ENTRY(entry);
            }
            break;
          case FQ_PROTO_UNBINDREQ:
            {
              if(fq_write_uint16(conn_s->cmd_fd, entry->cmd) ||
                 fq_write_uint32(conn_s->cmd_fd, entry->data.unbind->route_id) ||
                 fq_write_short_cmd(conn_s->cmd_fd,
                                    entry->data.unbind->exchange.len,
                                    entry->data.unbind->exchange.name) < 0) {
	CONNERR(conn_s, "write failed (unbindreq)");
                goto restart;
              }
              SAVE_ENTRY(entry);
            }
            break;
          default:
            CONNERR(conn_s, "unknown user-side cmd");
            free(entry);
        }
      }
      ck_fifo_spsc_dequeue_unlock(&conn_s->cmdq);

      if(conn_s->cmd_hb_needed) {
#ifdef DEBUG
          fq_debug(FQ_DEBUG_CONN, "-> heartbeat\n");
#endif
        if(fq_write_uint16(conn_s->cmd_fd, FQ_PROTO_HB)) {
          CONNERR(conn_s, "write failed (hb)");
          break;
        }
        conn_s->cmd_hb_needed = 0;
      }

      rv = fq_client_wfrw_internal(conn_s->cmd_fd, 1, 0, wait_ms, NULL);
      if(rv == 0) {
        wait_ms = (wait_ms >> 2) + wait_ms;
        if(conn_s->cmd_hb_ms && wait_ms > conn_s->cmd_hb_ms)
          wait_ms = conn_s->cmd_hb_ms;
        if(wait_ms > 1000) wait_ms = 1000;
      }
      else wait_ms = 50;
      fq_debug(FQ_DEBUG_CONN, "fq_client_wfrw_internal(cmd:%d) -> %d\n", conn_s->cmd_fd, rv);
      t = fq_gethrtime();
      hb_us = (unsigned long long)conn_s->cmd_hb_ms * 3 * 1000000ULL;
      if(conn_s->cmd_hb_last && hb_us &&
         conn_s->cmd_hb_last < (unsigned int) (t - hb_us)) {
        char errbuf[256];
        snprintf(errbuf, sizeof(errbuf), "heartbeat failed [%llu - %llu = %llu]",
                 (unsigned long long)t, (unsigned long long)conn_s->cmd_hb_last,
                 (unsigned long long)(t - conn_s->cmd_hb_last));
        CONNERR(conn_s, errbuf);
        break;
      }
      if(rv < 0) {
        CONNERR(conn_s, strerror(errno));
        break;
      }
      if(rv > 0) {
        bool handled = false;
        uint16_t hb;
        if(fq_read_uint16(conn_s->cmd_fd, &hb)) break;
        switch(hb) {
          case FQ_PROTO_HB:
#ifdef DEBUG
            fq_debug(FQ_DEBUG_CONN, "<- heartbeat\n");
#endif
            conn_s->cmd_hb_last = fq_gethrtime();
            conn_s->cmd_hb_needed = 1;
            break;
          case FQ_PROTO_STATUS:
            if(!last_entry || last_entry->cmd != FQ_PROTO_STATUSREQ) {
              CONNERR(conn_s, "protocol violation (status unexpected)");
              goto restart;
            }
            if(fq_read_status(conn_s->cmd_fd,
                              last_entry->data.status.callback,
                              last_entry->data.status.closure))
              goto restart;
            PROCESS_ENTRY(last_entry, 1);
            break;
          case FQ_PROTO_BIND:
            if(!last_entry || last_entry->cmd != FQ_PROTO_BINDREQ) {
              CONNERR(conn_s, "protocol violation (bind unexpected)");
              goto restart;
            }
            if(fq_read_uint32(conn_s->cmd_fd,
                              &last_entry->data.bind->out__route_id)) {
              if(conn_s->bind_hook) {
                if(conn_s->sync_hooks) {
                  enqueue_cmd_hook_req(conn_s, last_entry);
	  PROCESS_ENTRY(last_entry, 0);
	  handled = true;
                }
                else conn_s->bind_hook((fq_client)conn_s, last_entry->data.bind);
              }
              CONNERR(conn_s, "read failed (bind)");
              goto restart;
            }
            if(conn_s->bind_hook) {
              if(conn_s->sync_hooks) {
                enqueue_cmd_hook_req(conn_s, last_entry);
	PROCESS_ENTRY(last_entry, 0);
	handled = true;
              }
              else conn_s->bind_hook((fq_client)conn_s, last_entry->data.bind);
            }
            if(!handled) PROCESS_ENTRY(last_entry, 1);
            break;
          case FQ_PROTO_UNBIND:
            if(!last_entry || last_entry->cmd != FQ_PROTO_UNBINDREQ) {
              CONNERR(conn_s, "protocol violation (unbind unexpected)");
              goto restart;
            }
            if(fq_read_uint32(conn_s->cmd_fd,
                              &last_entry->data.unbind->out__success)) {
              if(conn_s->unbind_hook) {
                if(conn_s->sync_hooks) {
                  enqueue_cmd_hook_req(conn_s, last_entry);
                  PROCESS_ENTRY(last_entry, 0);
	  handled = true;
                }
                conn_s->unbind_hook((fq_client)conn_s, last_entry->data.unbind);
              }
              CONNERR(conn_s, "read failed (unbind)");
              goto restart;
            }
            if(conn_s->unbind_hook) {
              if(conn_s->sync_hooks) {
                enqueue_cmd_hook_req(conn_s, last_entry);
                PROCESS_ENTRY(last_entry, 0);
	handled = true;
                last_entry = NULL;
              }
              conn_s->unbind_hook((fq_client)conn_s, last_entry->data.unbind);
            }
            if(!handled) PROCESS_ENTRY(last_entry,1);
            break;
          default:
            CONNERR(conn_s, "protocol violation");
            goto restart;
            break;
        }
      }
    }
Esempio n. 11
0
File: fqc.c Progetto: denji/fq
int main(int argc, char **argv) {
  hrtime_t s0, s, f, f0;
  uint64_t cnt = 0, icnt = 0;
  int psize = 0, i = 0, rcvd = 0;
  fq_client c;
  fq_bind_req breq;
  fq_msg *m;
  signal(SIGPIPE, SIG_IGN);
  fq_client_init(&c, 0, logger);
  if(argc < 5) {
    fprintf(stderr, "%s <host> <port> <user> <pass> [size [count]]\n",
            argv[0]);
    exit(-1);
  }
  fq_client_creds(c, argv[1], atoi(argv[2]), argv[3], argv[4]);
  fq_client_heartbeat(c, 1000);
  fq_client_set_backlog(c, 10000, 100);
  fq_client_connect(c);

  memset(&breq, 0, sizeof(breq));
  memcpy(breq.exchange.name, "maryland", 8);
  breq.exchange.len = 8;
  breq.peermode = 0;
  breq.program = (char *)"prefix:\"test.prefix.\"";

  fq_client_bind(c, &breq);
  while(breq.out__route_id == 0) usleep(100);
  printf("route set -> %u\n", breq.out__route_id);
  if(breq.out__route_id == FQ_BIND_ILLEGAL) {
    fprintf(stderr, "Failure to bind...\n");
    exit(-1);
  }

  if(argc > 5) {
     psize = atoi(argv[5]);
  }
  printf("payload size -> %d\n", psize);
  if(argc > 6) {
    send_count = atoi(argv[6]);
  }
  printf("message count -> %d\n", send_count);

  s0 = s = fq_gethrtime();
  while(i < send_count || fq_client_data_backlog(c) > 0) {
    if(i < send_count) {
      m = fq_msg_alloc_BLANK(psize);
      memset(m->payload, 0, psize);
      fq_msg_exchange(m, "maryland", 8);
      fq_msg_route(m, "test.prefix.foo", 15);
      fq_msg_id(m, NULL);
      fq_client_publish(c, m);
      cnt++;
      i++;
      fq_msg_free(m);
    }
    else usleep(100);


    f = fq_gethrtime();
    while(m = fq_client_receive(c)) {
      icnt++;
      rcvd++;
      fq_msg_deref(m);
    }
    if(f-s > 1000000000) {
      print_rate(c, s, f, cnt, icnt);
      icnt = 0;
      cnt = 0;
      s = f;
    }
  }
  f0 = fq_gethrtime();
  print_rate(c, s0, f0, i, 0);
  do {
    icnt=0;
    while(m = fq_client_receive(c)) {
      icnt++;
      rcvd++;
      fq_msg_deref(m);
    }
  } while(rcvd < send_count);
  f0 = fq_gethrtime();
  print_rate(c, s0, f0, 0, rcvd);
  printf("Total received during test: %d\n", rcvd);

  (void) argc;
  return 0;
}
Esempio n. 12
0
/*
 * return 0: keep going (to write path)
 * return -1: busted
 * 
 * Read into one of N buffers so the processing thread 
 * can do the work separate from the read
 */
int
fq_buffered_msg_read(buffered_msg_reader *f,
                     void (*f_msg_handler)(void *, fq_msg *),
                     void *closure) {
  int rv;
  static char scratch_buf[IN_READ_BUFFER_SIZE];
  while(f->into_body < f->msg->payload_len) {
    fq_assert(f->copy);
    /* we need to be reading a largish payload */
    if(f->into_body >= MAX_MESSAGE_SIZE) {
      /* read into a scratch buffer */
      size_t readsize = f->copy->payload_len - f->into_body;
      if(readsize > sizeof(scratch_buf)) readsize = sizeof(scratch_buf);
      while((rv = read(f->fd, scratch_buf, readsize)) == -1 && errno == EINTR);
    }
    else {
      while((rv = read(f->fd, f->copy->payload + f->into_body,
                       CAPPED(f->copy->payload_len) - f->into_body)) == -1 && errno == EINTR);
    }
    if(rv < 0 && errno == EAGAIN) return 0;
    if(rv <= 0) {
      fq_debug(FQ_DEBUG_IO, "read error: %s\n", rv < 0 ? strerror(errno) : "end-of-line");
      return -1;
    }
    fq_debug(FQ_DEBUG_MSG, "%p <-- %d bytes for payload\n", (void *)f, rv);
    f->into_body += rv;
    if(f->into_body == f->copy->payload_len) {
      f->into_body = 0;
      goto message_done;
    }
  }
  while((rv = read(f->fd, f->scratch+f->nread, sizeof(f->scratch)-f->nread)) == -1 &&
        errno == EINTR);
  fq_debug(FQ_DEBUG_IO, "%p <-- %d bytes @ %d (%d)\n", (void *)f, rv, (int)f->nread,
          (int)f->nread + ((rv > 0) ? rv : 0));
  if(rv == -1 && errno == EAGAIN) return 0;
  if(rv <= 0) return -1;
  f->nread += rv;

  while(f->nread>0) {
    uint32_t body_available;
    int body_start;
    body_start = parse_message_headers(f->peermode,
                                       f->scratch+f->off, f->nread-f->off,
                                       f->msg);
    f->into_body = 0;
    fq_debug(FQ_DEBUG_MSG, "%d = parse(+%d, %d) -> %d\n",
            body_start, f->off, (int)f->nread-f->off,
            body_start ? (int)f->msg->payload_len : 0);
    if(body_start < 0) return -1;
    if(!body_start) {
      fq_debug(FQ_DEBUG_MSG, "incomplete message header...\n");
      memmove(f->scratch, f->scratch + f->off, f->nread - f->off);
      f->nread -= f->off;
      f->off = 0;
      return 0;
    }

    free_message_stack *tls_free_message_stack = NULL;
    int msg_stack_idx = msg_free_stack_select(f->msg->payload_len);
    if(msg_stack_idx >= 0) {
      if(tls_free_message_handle == NULL)
        tls_free_message_handle = free_message_handle_acquire();
      if(tls_free_message_handle->stacks[msg_stack_idx] == NULL) {
        /* lazy create/init the cleanup stack */
        tls_free_message_handle->stacks[msg_stack_idx] = malloc(sizeof(free_message_stack));
        fq_init_free_message_stack(tls_free_message_handle->stacks[msg_stack_idx],
                                   FREE_MSG_LIST_SIZE/(1 << (msg_stack_idx + MSG_FREE_BASE)),
                                   (1 << (msg_stack_idx + MSG_FREE_BASE)));
      }
      tls_free_message_stack = tls_free_message_handle->stacks[msg_stack_idx];
    }

    if(tls_free_message_stack) {
      /* We have a message... or the formal beginnings of one */
      f->copy = fq_pop_free_message_stack(tls_free_message_stack);
      if (f->copy == NULL) {
        /* ran out of entries in free list */
        f->copy = fq_msg_alloc_BLANK(tls_free_message_stack->alloc_size);
        if (f->copy == NULL) {
          /* this is bad, we can't alloc */
          fq_debug(FQ_DEBUG_MSG, "unable to malloc, OOM?\n");
          return -1;
        }
      }

      /* always 1 as this msg only lives until it's copied by a worker thread */
      memcpy(f->copy, f->msg, sizeof(fq_msg));
      f->copy->refcnt = 1;
      f->copy->free_fn = fq_free_msg_fn;

    } else {
      f->copy = fq_msg_alloc_BLANK(CAPPED(f->msg->payload_len));
      if (f->copy == NULL) {
        /* this is bad, we can't alloc */
        fq_debug(FQ_DEBUG_MSG, "unable to malloc, OOM?\n");
        return -1;
      }

      memcpy(f->copy, f->msg, sizeof(fq_msg));
      f->copy->refcnt = 1;
      f->copy->free_fn = NULL;
    }

    /* assign the cleanup stack for this message */
    f->copy->cleanup_handle = tls_free_message_stack ? tls_free_message_handle : NULL;
    memset(&f->copy->cleanup_stack_entry, 0, sizeof(ck_stack_entry_t));

    f->off += body_start;
    body_available = f->nread - f->off;
    if(f->copy->payload_len < body_available) body_available = f->copy->payload_len;
    memcpy(f->copy->payload, f->scratch+f->off, CAPPED(body_available));
    if(body_available == f->copy->payload_len) {
      f->off += body_available;
     message_done:
      f->copy->refcnt = 1;
      f->copy->payload_len = CAPPED(f->copy->payload_len);
      fq_debug(FQ_DEBUG_MSG, "message read... injecting\n");
      f->copy->arrival_time = fq_gethrtime();
      f_msg_handler(closure, f->copy);
      f->copy = NULL;
      memset(f->msg, 0, sizeof(fq_msg));
      /* It is still allocated and we are the sole owner, refcnt must be 1 */
      f->msg->refcnt = 1;
    }
    else {
      f->nread = 0;
      f->off = 0;
      f->into_body = body_available;
      fq_debug(FQ_DEBUG_MSG, "incomplete message... (%d needed)\n",
             (int)f->msg->payload_len - (int)f->into_body);
      return 0;
    }
  }
  return 0;
}
Esempio n. 13
0
static void *
fq_conn_worker(void *u) {
  int backoff = 0;
  fq_conn_s *conn_s = (fq_conn_s *)u;
  cmd_instr *last_entry = NULL;
  uint16_t expect;
  while(conn_s->stop == 0) {
   restart:
    expect = 0;
    if(fq_client_connect_internal(conn_s) == 0) {
      backoff = 0; /* we're good, restart our backoff */
    }

    while(conn_s->data_ready) {
      hrtime_t t;
      unsigned long long hb_us;
      struct timeval tv;
      int rv;
      cmd_instr *entry;
      ck_fifo_mpmc_entry_t *garbage;

      while(ck_fifo_mpmc_dequeue(&conn_s->cmdq, &entry, &garbage) == true) {
        free(garbage);
#ifdef DEBUG
        fq_debug(FQ_DEBUG_CONN, "client acting on user req 0x%04x\n", entry->cmd);
#endif
        switch(entry->cmd) {
          case FQ_PROTO_STATUSREQ:
            if(expect != 0) {
              if(conn_s->errorlog) conn_s->errorlog("protocol violation");
              goto restart;
            }
            fq_debug(FQ_DEBUG_CONN, "sending status request\n");
            if(fq_write_uint16(conn_s->cmd_fd, entry->cmd)) {
              free(entry);
              goto restart;
            }
            expect = FQ_PROTO_STATUS;
            last_entry = entry;
            break;
          case FQ_PROTO_HBREQ:
            fq_debug(FQ_DEBUG_CONN, "sending heartbeat request\n");
            if(fq_write_uint16(conn_s->cmd_fd, entry->cmd) ||
               fq_write_uint16(conn_s->cmd_fd, entry->data.heartbeat.ms)) {
              free(entry);
              goto restart;
            }
            conn_s->cmd_hb_ms = entry->data.heartbeat.ms;
            tv.tv_sec = (unsigned long)entry->data.heartbeat.ms / 1000;
            tv.tv_usec = 1000UL * (entry->data.heartbeat.ms % 1000);
            if(setsockopt(conn_s->cmd_fd, SOL_SOCKET, SO_RCVTIMEO,
                          &tv, sizeof(tv)))
              CONNERR(conn_s, strerror(errno));
            tv.tv_sec = (unsigned long)entry->data.heartbeat.ms / 1000;
            tv.tv_usec = 1000UL * (entry->data.heartbeat.ms % 1000);
            if(setsockopt(conn_s->cmd_fd, SOL_SOCKET, SO_SNDTIMEO,
                          &tv, sizeof(tv)))
              CONNERR(conn_s, strerror(errno));
            conn_s->cmd_hb_last = fq_gethrtime();
            free(entry);
            break;
          case FQ_PROTO_BINDREQ:
            {
              unsigned short peermode = entry->data.bind->peermode ? 1 : 0;
              if(expect != 0) {
                if(conn_s->errorlog) conn_s->errorlog("protocol violation");
                goto restart;
              }
              if(fq_write_uint16(conn_s->cmd_fd, entry->cmd) ||
                 fq_write_uint16(conn_s->cmd_fd, peermode) ||
                 fq_write_short_cmd(conn_s->cmd_fd,
                                    entry->data.bind->exchange.len,
                                    entry->data.bind->exchange.name) < 0 ||
                 fq_write_short_cmd(conn_s->cmd_fd,
                                    strlen(entry->data.bind->program),
                                    entry->data.bind->program) < 0) {
                goto restart;
              }
              expect = FQ_PROTO_BIND;
              last_entry = entry;
            }
            break;
          case FQ_PROTO_UNBINDREQ:
            {
              if(expect != 0) {
                if(conn_s->errorlog) conn_s->errorlog("protocol violation");
                goto restart;
              }
              if(fq_write_uint16(conn_s->cmd_fd, entry->cmd) ||
                 fq_write_uint32(conn_s->cmd_fd, entry->data.unbind->route_id) ||
                 fq_write_short_cmd(conn_s->cmd_fd,
                                    entry->data.unbind->exchange.len,
                                    entry->data.unbind->exchange.name) < 0) {
                goto restart;
              }
              expect = FQ_PROTO_UNBIND;
              last_entry = entry;
            }
            break;
          default:
            if(conn_s->errorlog) conn_s->errorlog("unknown user-side cmd");
            free(entry);
        }
      }

      if(conn_s->cmd_hb_needed) {
#ifdef DEBUG
          fq_debug(FQ_DEBUG_CONN, "-> heartbeat\n");
#endif
        if(fq_write_uint16(conn_s->cmd_fd, FQ_PROTO_HB)) break;
        conn_s->cmd_hb_needed = 0;
      }

      rv = fq_client_wfrw_internal(conn_s->cmd_fd, 1, 0, 50, NULL);
      t = fq_gethrtime();
      hb_us = (unsigned long long)conn_s->cmd_hb_ms * 3 * 1000000ULL;
      if(conn_s->cmd_hb_last && hb_us &&
         conn_s->cmd_hb_last < (unsigned int) (t - hb_us)) {
        char errbuf[256];
        snprintf(errbuf, sizeof(errbuf), "heartbeat failed [%llu - %llu = %llu]",
                 (unsigned long long)t, (unsigned long long)conn_s->cmd_hb_last,
                 (unsigned long long)(t - conn_s->cmd_hb_last));
        CONNERR(conn_s, errbuf);
        break;
      }
      if(rv < 0) {
        CONNERR(conn_s, strerror(errno));
        break;
      }
      if(rv > 0) {
        uint16_t hb;
        if(fq_read_uint16(conn_s->cmd_fd, &hb)) break;
        switch(hb) {
          case FQ_PROTO_HB:
#ifdef DEBUG
            fq_debug(FQ_DEBUG_CONN, "<- heartbeat\n");
#endif
            conn_s->cmd_hb_last = fq_gethrtime();
            conn_s->cmd_hb_needed = 1;
            break;
          case FQ_PROTO_STATUS:
            if(expect != FQ_PROTO_STATUS) {
              if(conn_s->errorlog) conn_s->errorlog("protocol violation");
              goto restart;
            }
            if(fq_read_status(conn_s->cmd_fd,
                              last_entry->data.status.callback,
                              last_entry->data.status.closure))
              goto restart;
            expect = 0;
            break;
          case FQ_PROTO_BIND:
            if(expect != FQ_PROTO_BIND) {
              if(conn_s->errorlog) conn_s->errorlog("protocol violation");
              goto restart;
            }
            if(fq_read_uint32(conn_s->cmd_fd,
                              &last_entry->data.bind->out__route_id))
              goto restart;
            expect = 0;
            break;
          case FQ_PROTO_UNBIND:
            if(expect != FQ_PROTO_UNBIND) {
              if(conn_s->errorlog) conn_s->errorlog("protocol violation");
              goto restart;
            }
            if(fq_read_uint32(conn_s->cmd_fd,
                              &last_entry->data.unbind->out__success))
              goto restart;
            expect = 0;
            break;
          default:
            if(conn_s->errorlog) conn_s->errorlog("protocol violation");
            goto restart;
            break;
        }
      }
    }

#ifdef DEBUG
    fq_debug(FQ_DEBUG_CONN, "[cmd] connection failed: %s\n", conn_s->error);
#endif
    usleep(backoff);
    backoff += 10000;
  }
  fq_client_disconnect_internal(conn_s);
  return (void *)NULL;
}