/* * tnt_rpl() * * create and initialize replication stream; * * s - stream pointer, maybe NULL * * if stream pointer is NULL, then new stream will be created. * * returns stream pointer, or NULL on error. */ struct tnt_stream *tnt_rpl(struct tnt_stream *s) { int allocated = s == NULL; s = tnt_stream_init(s); if (s == NULL) return NULL; /* allocating stream data */ s->data = tnt_mem_alloc(sizeof(struct tnt_stream_rpl)); if (s->data == NULL) goto error; memset(s->data, 0, sizeof(struct tnt_stream_rpl)); /* initializing interfaces */ s->read = NULL; s->read_request = tnt_rpl_request; s->read_reply = NULL; s->read_tuple = NULL; s->write = NULL; s->writev = NULL; s->free = tnt_rpl_free; /* initializing internal data */ struct tnt_stream_rpl *sr = TNT_RPL_CAST(s); sr->net = NULL; return s; error: if (s->data) { tnt_mem_free(s->data); s->data = NULL; } if (allocated) tnt_stream_free(s); return NULL; }
static int tc_wal_printer_from_rpl(struct tnt_iter *i) { struct tnt_request *r = TNT_IREQUEST_PTR(i); struct tnt_stream_rpl *s = TNT_RPL_CAST(TNT_IREQUEST_STREAM(i)); tc_wal_print(&s->hdr, r); return 0; }
static void tnt_rpl_free(struct tnt_stream *s) { struct tnt_stream_rpl *sr = TNT_RPL_CAST(s); if (sr->net) { /* network stream should not be free'd here */ sr->net = NULL; } tnt_mem_free(s->data); }
/* * tnt_rpl_open() * * connect to a server and initialize handshake; * * s - replication stream pointer * lsn - start lsn * * network stream must be properly initialized before * this function called (see ttnt_rpl_net, tnt_set). * * returns 0 on success, or -1 on error. */ int tnt_rpl_open(struct tnt_stream *s, uint64_t lsn) { struct tnt_stream_rpl *sr = TNT_RPL_CAST(s); /* intializing connection */ if (tnt_init(sr->net) == -1) return -1; if (tnt_connect(sr->net) == -1) return -1; /* sending initial lsn */ struct tnt_stream_net *sn = TNT_SNET_CAST(sr->net); if (tnt_io_send_raw(sn, (char*)&lsn, sizeof(lsn), 1) == -1) return -1; /* reading and checking version */ uint32_t version = 0; if (tnt_io_recv_raw(sn, (char*)&version, sizeof(version), 1) == -1) return -1; if (version != tnt_rpl_version) return -1; return 0; }
static int tnt_rpl_request(struct tnt_stream *s, struct tnt_request *r) { struct tnt_stream_rpl *sr = TNT_RPL_CAST(s); struct tnt_stream_net *sn = TNT_SNET_CAST(sr->net); /* fetching header */ if (tnt_io_recv(sn, (char*)&sr->hdr, sizeof(sr->hdr)) == -1) return -1; /* fetching row header */ if (tnt_io_recv(sn, (char*)&sr->row, sizeof(sr->row)) == -1) return -1; /* preparing pseudo iproto header */ struct tnt_header hdr_iproto; hdr_iproto.type = sr->row.op; hdr_iproto.len = sr->hdr.len - sizeof(struct tnt_log_row_v11); hdr_iproto.reqid = 0; /* deserializing operation */ if (tnt_request_from(r, (tnt_request_t)tnt_rpl_recv_cb, sr->net, &hdr_iproto) == -1) return -1; return 0; }
/* * tnt_rpl_attach() * * attach network stream (tnt_stream_net object); * * s - replication stream pointer */ void tnt_rpl_attach(struct tnt_stream *s, struct tnt_stream *net) { TNT_RPL_CAST(s)->net = net; }
/* * tnt_rpl_close() * * close a connection; * * s - replication stream pointer * * returns 0 on success, or -1 on error. */ void tnt_rpl_close(struct tnt_stream *s) { struct tnt_stream_rpl *sr = TNT_RPL_CAST(s); if (sr->net) tnt_close(s); }