コード例 #1
0
ファイル: jthreadtest.c プロジェクト: omniti-labs/jlog
void *writer(void *unused) {
  jlog_ctx *ctx;
  int i;
  char foo[72];
  ctx = jlog_new(LOGNAME);
  memset(foo, 'X', sizeof(foo)-1);
  foo[sizeof(foo)-1] = '\0';
  if(jlog_ctx_open_writer(ctx) != 0) {
    fprintf(stderr, "jlog_ctx_open_writer failed: %d %s\n", jlog_ctx_err(ctx), jlog_ctx_err_string(ctx));
    croak();
  }

#ifdef TEST_UNIT_LIMIT
  newsize = 1024*1024 + (((intptr_t)unused) % (1024 * 1024));
  fprintf(stderr, "writer setting new unit_limit to %d\n", (int)newsize);
  jlog_ctx_alter_journal_size(ctx, newsize);
#endif
  for(i=0;i<10000;i++) {
    int rv;
    rv = jlog_ctx_write(ctx, foo, strlen(foo));
    if(rv != 0) {
      fprintf(stderr, "jlog_ctx_write_message failed: %d %s\n", jlog_ctx_err(ctx), jlog_ctx_err_string(ctx));
      /* abort(); */
    }
    usleep(100);
  }
  fprintf(stderr, "writer thinks unit_limit is %d\n", ctx->meta->unit_limit);
  jlog_ctx_close(ctx);
  writer_done = 1;
  return 0;
}
コード例 #2
0
ファイル: jthreadtest.c プロジェクト: omniti-labs/jlog
void jcreate(jlog_safety s) {
  jlog_ctx *ctx;
  const char *label = NULL;
  
  switch (s) {
    case JLOG_ALMOST_SAFE: label = "almost safe"; break;
    case JLOG_UNSAFE:      label = "unsafe"; break;
    case JLOG_SAFE:        label = "safe"; break;
  }
  fprintf(stderr, "jcreate %s in %s mode\n", LOGNAME, label);
  
  ctx = jlog_new(LOGNAME);
  jlog_ctx_alter_journal_size(ctx, 102400);
  jlog_ctx_alter_safety(ctx, s);
  if(jlog_ctx_init(ctx) != 0) {
    fprintf(stderr, "jlog_ctx_init failed: %d %s\n", jlog_ctx_err(ctx), jlog_ctx_err_string(ctx));
    if(jlog_ctx_err(ctx) != JLOG_ERR_CREATE_EXISTS) exit(0);
  } else {
    jlog_ctx_add_subscriber(ctx, MASTER, JLOG_BEGIN);
  }
  jlog_ctx_close(ctx);
}
コード例 #3
0
ファイル: fqd_queue_jlog.c プロジェクト: HeinrichHartmann/fq
static fq_msg *queue_jlog_dequeue(fqd_queue_impl_data f) {
  struct queue_jlog *d = (struct queue_jlog *)f;
  jlog_message msg;
  fq_msg *m;
  if(d->count == 0 && d->last_seen_nenqueued == d->nenqueued) return NULL;
 retry:
  if(d->count <= 0) {
    d->count = jlog_ctx_read_interval(d->reader, &d->start, &d->finish);
    fq_debug(FQ_DEBUG_IO, "jlog read batch count -> %d\n", d->count);
    if(d->count < 0) {
      char idxfile[PATH_MAX];
      fq_debug(FQ_DEBUG_IO, "jlog_ctx_read_interval: %s\n",
               jlog_ctx_err_string(d->reader));
      switch (jlog_ctx_err(d->reader)) {
        case JLOG_ERR_FILE_CORRUPT:
        case JLOG_ERR_IDX_CORRUPT:
          jlog_repair_datafile(d->reader, d->start.log);
          jlog_repair_datafile(d->reader, d->start.log + 1);
          fq_debug(FQ_DEBUG_IO,
                "jlog reconstructed, deleting corresponding index.\n");
          STRSETDATAFILE(d->reader, idxfile, d->start.log);
          strncpy(idxfile + strlen(idxfile), INDEX_EXT, sizeof(idxfile) - strlen(idxfile));
          unlink(idxfile);
          STRSETDATAFILE(d->reader, idxfile, d->start.log + 1);
          strncpy(idxfile + strlen(idxfile), INDEX_EXT, sizeof(idxfile) - strlen(idxfile));
          unlink(idxfile);
          break;
        default:
          break;
      }
    }
    if(d->count <= 0) return NULL;
  }
  if(jlog_ctx_read_message(d->reader, &d->start, &msg) == -1) {
    d->count = 0;
    return NULL;
  }
  if(d->last_dequeued.log > d->start.log ||
     (d->last_dequeued.log == d->start.log &&
      d->last_dequeued.marker > d->start.marker)) {
    d->count--;
    JLOG_ID_ADVANCE(&d->start);
    goto retry;
  }
  if(msg.mess_len < sizeof(fq_msg)-1)
    m = NULL;
  else {
    off_t expected_len;
    uint32_t payload_len;
    m = (fq_msg *)msg.mess;
    memcpy(&payload_len, &m->payload_len, sizeof(m->payload_len));
    expected_len = offsetof(fq_msg, payload) + payload_len;
    if(expected_len != msg.mess_len) m = NULL;
    else {
      m = malloc(expected_len);
      memcpy(m, msg.mess, expected_len);
      m->sender_msgid.id.u32.p3 = d->start.log;
      m->sender_msgid.id.u32.p4 = d->start.marker;
    }
  }
  d->count--;
  fq_debug(FQ_DEBUG_IO, "jlog batch count -> %d\n", d->count);
  if(d->count == 0) {
    if(d->auto_chkpt) {
      jlog_ctx_read_checkpoint(d->reader, &d->start);
    }
  }
  d->last_dequeued = d->start;
  JLOG_ID_ADVANCE(&d->start);
  ck_pr_inc_uint(&d->last_seen_nenqueued);
  return m;
}
コード例 #4
0
void *
noit_jlog_thread_main(void *e_vptr) {
  int mask, bytes_read;
  eventer_t e = e_vptr;
  acceptor_closure_t *ac = e->closure;
  noit_jlog_closure_t *jcl = ac->service_ctx;
  char inbuff[sizeof(jlog_id)];

  eventer_set_fd_blocking(e->fd);

  while(1) {
    jlog_id client_chkpt;
    int sleeptime = (ac->cmd == NOIT_JLOG_DATA_TEMP_FEED) ?
                      1 : DEFAULT_SECONDS_BETWEEN_BATCHES;
    jlog_get_checkpoint(jcl->jlog, ac->remote_cn, &jcl->chkpt);
    jcl->count = jlog_ctx_read_interval(jcl->jlog, &jcl->start, &jcl->finish);
    if(jcl->count < 0) {
      char idxfile[PATH_MAX];
      noitL(noit_error, "jlog_ctx_read_interval: %s\n",
            jlog_ctx_err_string(jcl->jlog));
      switch (jlog_ctx_err(jcl->jlog)) {
        case JLOG_ERR_FILE_CORRUPT:
        case JLOG_ERR_IDX_CORRUPT:
          jlog_repair_datafile(jcl->jlog, jcl->start.log);
          jlog_repair_datafile(jcl->jlog, jcl->start.log + 1);
          noitL(noit_error,
                "jlog reconstructed, deleting corresponding index.\n");
          STRSETDATAFILE(jcl->jlog, idxfile, jcl->start.log);
          strlcat(idxfile, INDEX_EXT, sizeof(idxfile));
          unlink(idxfile);
          STRSETDATAFILE(jcl->jlog, idxfile, jcl->start.log + 1);
          strlcat(idxfile, INDEX_EXT, sizeof(idxfile));
          unlink(idxfile);
          goto alldone;
          break;
        default:
          goto alldone;
      }
    }
    if(jcl->count > MAX_ROWS_AT_ONCE) {
      /* Artificially set down the range to make the batches a bit easier
       * to handle on the stratcond/postgres end.
       * However, we must have more data, so drop the sleeptime to 0
       */
      jcl->count = MAX_ROWS_AT_ONCE;
      jcl->finish.marker = jcl->start.marker + jcl->count;
      sleeptime = 0;
    }
    if(jcl->count > 0) {
      if(noit_jlog_push(e, jcl)) {
        goto alldone;
      }
      /* Read our jlog_id accounting for possibly short reads */
      bytes_read = 0;
      while(bytes_read < sizeof(jlog_id)) {
        int len;
        if((len = e->opset->read(e->fd, inbuff + bytes_read,
                                 sizeof(jlog_id) - bytes_read,
                                 &mask, e)) <= 0)
          goto alldone;
        bytes_read += len;
      }
      memcpy(&client_chkpt, inbuff, sizeof(jlog_id));
      /* Fix the endian */
      client_chkpt.log = ntohl(client_chkpt.log);
      client_chkpt.marker = ntohl(client_chkpt.marker);
  
      if(memcmp(&jcl->chkpt, &client_chkpt, sizeof(jlog_id))) {
        noitL(noit_error,
              "client %s submitted invalid checkpoint %u:%u expected %u:%u\n",
              ac->remote_cn, client_chkpt.log, client_chkpt.marker,
              jcl->chkpt.log, jcl->chkpt.marker);
        goto alldone;
      }
      gettimeofday(&jcl->feed_stats->last_checkpoint, NULL);
      jlog_ctx_read_checkpoint(jcl->jlog, &jcl->chkpt);
    }
    else {
      /* we have nothing to write -- maybe we have no checks configured...
       * If this is the case "forever", the remote might disconnect and
       * we would never know. Do the painful work of detecting a
       * disconnected client.
       */
      struct pollfd pfd;
      pfd.fd = e->fd;
      pfd.events = POLLIN | POLLHUP | POLLRDNORM;
      pfd.revents = 0;
      if(poll(&pfd, 1, 0) != 0) {
        /* normally, we'd recv PEEK|DONTWAIT.  However, the client should
         * not be writing to us.  So, we know we can't have any legitimate
         * data on this socket (true even though this is SSL). So, if we're
         * here then "shit went wrong"
         */
        noitL(noit_error, "jlog client %s disconnected while idle\n",
              ac->remote_cn);
        goto alldone;
      }
    }
    if(sleeptime) sleep(sleeptime);
  }

 alldone:
  e->opset->close(e->fd, &mask, e);
  noit_atomic_dec32(&jcl->feed_stats->connections);
  noit_jlog_closure_free(jcl);
  acceptor_closure_free(ac);
  return NULL;
}
コード例 #5
0
ファイル: jthreadtest.c プロジェクト: omniti-labs/jlog
int main(int argc, char **argv) {
  int i;
  char *toremove = NULL;
  jlog_safety safety = JLOG_ALMOST_SAFE;
  pthread_t tid[THRCNT], wtid[WTHRCNT];
  void *foo;
 
#if _WIN32 
  mem_init();
#endif

  if(argc == 3) {
    if(!strcmp(argv[1], "safety")) {
      if(!strcmp(argv[2], "unsafe"))
        safety = JLOG_UNSAFE;
      else if(!strcmp(argv[2], "almost_safe"))
        safety = JLOG_ALMOST_SAFE;
      else if(!strcmp(argv[2], "safe"))
        safety = JLOG_SAFE;
      else {
        fprintf(stderr, "invalid safety option\n");
        usage();
      }
    } else if(!strcmp(argv[1], "only")) {
      if(!strcmp(argv[2], "read")) only_read = 1;
      else if(!strcmp(argv[2], "write")) only_write = 1;
      else usage();
    } else if(!strcmp(argv[1], "remove")) {
      toremove = argv[2];
    } else {
      usage();
    }
  } else if(argc < 3 || argc > 3) {
    usage();
  }

  jcreate(safety);

  if(toremove) {
    jlog_ctx *ctx;
    ctx = jlog_new(LOGNAME);
    if(jlog_ctx_open_writer(ctx) != 0) {
      fprintf(stderr, "jlog_ctx_open_writer failed: %d %s\n", jlog_ctx_err(ctx), jlog_ctx_err_string(ctx));
      croak();
    }
    jlog_ctx_remove_subscriber(ctx, argv[2]);
    jlog_ctx_close(ctx);
    exit(0);
  }
  if(!only_write) {
    for(i=0; i<THRCNT; i++) {
      pthread_create(&tid[i], NULL, reader, (void *)(uintptr_t)i);
      fprintf(stderr, "[%d] started reader\n", (int)(uintptr_t)tid[i]);
    }
  }
  if(!only_read) {
    fprintf(stderr, "starting writers..\n");
    for(i=0; i<WTHRCNT; i++) {
      pthread_create(&wtid[i], NULL, writer, (void *)(uintptr_t)i);
      fprintf(stderr, "[%d] started writer\n", (int)(uintptr_t)wtid[i]);
    }
  } else {
    sleep(5);
    writer_done = 1;
  }
  if(!only_write) {
    for(i=0; i<THRCNT; i++) {
      pthread_join(tid[i], &foo);
      fprintf(stderr, "[%d] joined, read %d\n", i, (int)(uintptr_t)foo);
    }
  }
  if(!only_read) {
    for(i=0; i<WTHRCNT; i++) {
      pthread_join(wtid[i], &foo);
      fprintf(stderr, "[%d] joined, write %d\n", i, (int)(uintptr_t)foo);
    }
  }
  if(error) fprintf(stderr, "errors occurred\n");
  return 0;
}
コード例 #6
0
ファイル: jthreadtest.c プロジェクト: omniti-labs/jlog
void *reader(void *unused) {
  jlog_ctx *ctx;
  char subname[32];
  int tcount = 0, fcount = 0;
  int prev_err = 0;
  int subno = (int)(uintptr_t)unused;
  snprintf(subname, sizeof(subname), "sub-%02d", subno);
reader_retry:
  ctx = jlog_new(LOGNAME);
  if(jlog_ctx_open_reader(ctx, subname) != 0) {
    if(prev_err == 0) {
      prev_err = jlog_ctx_err(ctx);
      jlog_ctx_close(ctx);
      ctx = jlog_new(LOGNAME);
      if(prev_err == JLOG_ERR_INVALID_SUBSCRIBER) {
        fprintf(stderr, "[%02d] invalid subscriber, init...\n", subno);
        if(jlog_ctx_open_writer(ctx) != 0) {
          fprintf(stderr, "[%02d] jlog_ctx_open_writer failed: %d %s\n", subno, jlog_ctx_err(ctx), jlog_ctx_err_string(ctx));
        } else {
          if(jlog_ctx_add_subscriber(ctx, subname, JLOG_BEGIN) != 0) {
            fprintf(stderr, "[%02d] jlog_ctx_add_subscriber failed: %d %s\n", subno, jlog_ctx_err(ctx), jlog_ctx_err_string(ctx));
          } else {
            jlog_ctx_close(ctx);
            goto reader_retry;
          }
        }
      }
    }
    fprintf(stderr, "[%02d] jlog_ctx_open_reader failed: %d %s\n", subno, jlog_ctx_err(ctx), jlog_ctx_err_string(ctx));
    croak();
  }
  fprintf(stderr, "[%02d] reader started\n", subno);
  while(1) {
    char begins[20], ends[20];
    jlog_id begin, end;
    int count;
    jlog_message message;
    if((count = jlog_ctx_read_interval(ctx, &begin, &end)) == -1) {
      fprintf(stderr, "jlog_ctx_read_interval failed: %d %s\n", jlog_ctx_err(ctx), jlog_ctx_err_string(ctx));
      croak();
    }
    jlog_snprint_logid(begins, sizeof(begins), &begin);
    jlog_snprint_logid(ends, sizeof(ends), &end);
    if(count > 0) {
      int i;
      //fprintf(stderr, "[%02d] reader (%s, %s] count: %d\n", subno, begins, ends, count);
      for(i=0; i<count; i++, JLOG_ID_ADVANCE(&begin)) {
        end = begin;
        if(jlog_ctx_read_message(ctx, &begin, &message) != 0) {
          if(jlog_ctx_err(ctx) == JLOG_ERR_CLOSE_LOGID) {
            /* fine */
          } else {
            fcount++;
            jlog_snprint_logid(begins, sizeof(begins), &begin);
            fprintf(stderr, "[%02d] read failed @ %s: %d %s\n", subno, begins, jlog_ctx_err(ctx), jlog_ctx_err_string(ctx));
          }
        } else {
          tcount++;
          jlog_snprint_logid(begins, sizeof(begins), &begin);
          /* fprintf(stderr, "[%02d] read: [%s]\n\t'%.*s'\n", subno, begins,
                  message.mess_len, (char *)message.mess); */
        }
      }
      if(jlog_ctx_read_checkpoint(ctx, &end) != 0) {
        fprintf(stderr, "[%02d] checkpoint failed: %d %s\n", subno, jlog_ctx_err(ctx), jlog_ctx_err_string(ctx));
      } else {
        fprintf(stderr, "[%02d] \tcheckpointed...\n", subno);
      }
    } else {
      if(writer_done == 1) break;
    }
  }
  fprintf(stderr, "[%02d] reader read %d, failed %d\n", subno, tcount, fcount);
  jlog_ctx_close(ctx);
  return (void *)(uintptr_t)tcount;
}