void *spr_worker(void *data) { int rc=-1, nc; void *sp=NULL, *set; size_t len; char *buf; set = kv_set_new(); sp = kv_spoolreader_new(CF.dir); if (!sp) goto done; while (kv_spool_read(sp,set,1) > 0) { if (set_to_buf(set,&buf,&len) < 0) goto done; assert(len < MAX_BUF); nc = nn_send(CF.ingress_socket_push, buf, len, 0); free(buf); if (nc < 0) { fprintf(stderr,"nn_send: %s\n", nn_strerror(errno)); goto done; } ts_add(CF.spr_msgs_ts, CF.now, NULL); if (CF.shutdown) break; } done: CF.shutdown = 1; kv_set_free(set); if (sp) kv_spoolreader_free(sp); return NULL; }
/****************************************************************************** * kvsp-spr: a spool reader, for manually inspecting contents of a spool *****************************************************************************/ int main(int argc, char *argv[]) { char *exe = argv[0]; int opt; while ( (opt = getopt(argc, argv, "fv+")) != -1) { switch (opt) { case 'v': verbose++; break; case 'f': mode=mode_nop; break; default: usage(exe); break; } } if (optind < argc) dir=argv[optind++]; else usage(exe); void *sp = kv_spoolreader_new(dir); if (!sp) exit(-1); void *set = kv_set_new(); while (kv_spool_read(sp,set,1) > 0) { switch(mode) { case mode_nop: continue; case mode_out: kv_set_dump(set,stdout); printf("\n"); break; default: assert(0); break; } } done: kv_spoolreader_free(sp); kv_set_free(set); return 0; }
int main(int argc, char *argv[]) { void *sp=NULL; void *set=NULL; int opt,rc=-1; char *config_file; set = kv_set_new(); utarray_new(output_keys, &ut_str_icd); utarray_new(output_defaults, &ut_str_icd); utarray_new(output_types,&ut_int_icd); utstring_new(tmp); while ( (opt = getopt(argc, argv, "v+d:b:s")) != -1) { switch (opt) { case 'v': verbose++; break; case 's': push_mode++; break; case 'd': spool=strdup(optarg); break; case 'b': config_file=strdup(optarg); break; default: usage(argv[0]); break; } } if (optind < argc) pub_transport = argv[optind++]; if (!pub_transport) usage(argv[0]); if (spool == NULL) usage(argv[0]); if (parse_config(config_file) < 0) goto done; if ( !(pub_context = zmq_init(1))) goto done; if ( !(pub_socket = zmq_socket(pub_context, push_mode?ZMQ_PUSH:ZMQ_PUB))) goto done; if (zmq_setsockopt(pub_socket, ZMQ_SNDHWM, &hwm, sizeof(hwm))) goto done; if (zmq_bind(pub_socket, pub_transport) == -1) goto done; sp = kv_spoolreader_new(spool); if (!sp) goto done; while (kv_spool_read(sp,set,1) > 0) { /* read til interrupted by signal */ zmq_msg_t part; if (set_to_binary(set,&part) < 0) goto done; rc = zmq_sendmsg(pub_socket, &part, 0); zmq_msg_close(&part); if (rc == -1) goto done; } rc = 0; done: if (rc) fprintf(stderr,"zmq: %s %s\n", pub_transport, zmq_strerror(errno)); if (pub_socket) zmq_close(pub_socket); if (pub_context) zmq_term(pub_context); if (sp) kv_spoolreader_free(sp); kv_set_free(set); utarray_free(output_keys); utarray_free(output_defaults); utarray_free(output_types); utstring_free(tmp); return 0; }
int periodic_work() { int rc = -1, kc; shift_buffers(); dump_stats(); #if 1 while (have_capacity()) { kc = kv_spool_read(cfg.sp,cfg.set,0); if (kc < 0) goto done; // error if (kc == 0) break; // no data cfg.ompp++; if (set_to_binary(cfg.set, cfg.s)) goto done; append_to_client_buf(cfg.s); } mark_writable(); #endif rc = 0; done: return rc; }
/****************************************************************************** * the test itself *****************************************************************************/ int main(int argc, char *argv[]) { char *dir = mktmpdir(); void *sp = kv_spoolwriter_new(dir); if (!sp) exit(-1); void *set = kv_set_new(); kv_adds(set, "hello", "again"); kv_adds(set, "second", "life"); kv_spool_write(sp,set); /* scan spool to validate expected file creation */ scan_spool(0); /* replace a value in the set, spool the set out. it should append * to the spool file previously created. */ printf("spooling second frame\n"); kv_adds(set, "second", "time"); kv_spool_write(sp,set); kv_spoolwriter_free(sp); /* verify spool has updated according to expectation */ scan_spool(0); printf("clear set\n"); kv_set_clear(set); /* loop over them */ kv_t *kv = NULL; while ( (kv = kv_next(set, kv))) { printf("key [%.*s], val [%.*s]\n", kv->klen, kv->key, kv->vlen, kv->val); } printf("reading from spool\n"); /* now try reading the spool */ sp = kv_spoolreader_new(dir); int rc; while ( (rc=kv_spool_read(sp, set, 0)) == 1) { printf("reader read frame:\n"); kv = NULL; while ( (kv = kv_next(set, kv))) { printf(" key [%.*s], val [%.*s]\n", kv->klen, kv->key, kv->vlen, kv->val); } } printf("kv_spool_read returned %d\n", rc); kv_spoolreader_free(sp); /* now reset it and read again */ printf("resetting the spool directory for another round of reading\n"); sp_reset(dir); sp = kv_spoolreader_new(dir); while ( (rc=kv_spool_read(sp, set, 0)) == 1) { printf("reader read frame:\n"); kv = NULL; while ( (kv = kv_next(set, kv))) { printf(" key [%.*s], val [%.*s]\n", kv->klen, kv->key, kv->vlen, kv->val); } } printf("kv_spool_read returned %d\n", rc); kv_spoolreader_free(sp); kv_set_free(set); scan_spool(1); return 0; }
/* flush as much pending output to the client as it can handle. */ void feed_client(int ready_fd, int events) { int *fd=NULL, rc, pos, rv, *p; char *buf, tmp[100]; size_t len; UT_string **s=NULL; /* find the fd in our list */ while ( (fd=(int*)utarray_next(cfg.clients,fd))) { s=(UT_string**)utarray_next(cfg.outbufs,s); assert(s); pos = utarray_eltidx(cfg.clients, fd); if (ready_fd == *fd) break; } assert(fd); if (cfg.verbose > 1) { fprintf(stderr, "pollout:%c pollin: %c\n", (events & EPOLLOUT)?'1':'0', (events & EPOLLIN) ?'1':'0'); } /* before we write to the client, drain any input or closure */ rv = recv(*fd, tmp, sizeof(tmp), MSG_DONTWAIT); if (rv == 0) { fprintf(stderr,"client closed (eof)\n"); close(*fd); /* deletes epoll instances on *fd too */ discard_client_buffers(pos); return; } if ((events & EPOLLOUT) == 0) return; /* send the pending buffer to the client */ p = (int*)utarray_eltptr(cfg.outidxs,pos); buf = utstring_body(*s) + *p; len = utstring_len(*s) - *p; rc = send(*fd, buf, len, MSG_DONTWAIT); if (cfg.verbose) fprintf(stderr,"sent %d/%d bytes\n", rc, (int)len); /* test for client closure or error. */ if (rc < 0) { if ((errno == EWOULDBLOCK) || (errno == EAGAIN)) return; fprintf(stderr,"client closed (%s)\n", strerror(errno)); close(*fd); /* deletes all epoll instances on *fd too */ discard_client_buffers(pos); return; } /* advance output index in the output buffer; we wrote rc bytes */ if (rc < len) { *p += rc; cfg.obpp += rc; } else { *p = 0; utstring_clear(*s); // buffer emptied mod_epoll(EPOLLIN,*fd); // remove EPOLLOUT } #if 1 shift_buffers(); int kc; while (have_capacity()) { kc = kv_spool_read(cfg.sp,cfg.set,0); if (kc < 0) goto done; // error if (kc == 0) break; // no data cfg.ompp++; if (set_to_binary(cfg.set, cfg.s)) goto done; append_to_client_buf(cfg.s); } mark_writable(); done: return; #endif }