static int fqd_http_reset_to_checkpoint(struct http_req *req) { fqd_config *config = fqd_config_get(); const char *cpname = get_ht_value(&req->query_params, "cpname"); const char *qname = get_ht_value(&req->query_params, "qname"); fq_rk qn; fq_rk_from_str(&qn, qname); fqd_queue *queue = fqd_config_get_registered_queue(config, &qn); if (strcmp(cpname, "fq") == 0) { fqd_http_error_json(req->client, "'fq' is a reserved name, cannot be used for a checkpoint name"); req->close = 1; return 0; } if (queue == NULL) { fqd_http_error_json_f(req->client, "Cannot find registered queue '%s'", qname); req->close = 1; return 0; } int rv = queue->impl->reset_checkpoint(queue->impl_data, cpname); if (rv == -1) { fqd_http_error_json(req->client, "Checkpoint does not exist"); req->close = 1; return 0; } if (rv < 0) { fqd_http_error_json(req->client, "Unknown error"); req->close = 1; return 0; } fqd_http_success_json_f(req->client, "'%s' reset to checkpoint '%s'", qname, cpname); req->close = 1; fq_debug(FQ_DEBUG_HTTP, ".on_complete -> reset_to_checkpoint on [%s] for queue [%s]\n", cpname, qname); return 0; }
extern void fqd_data_subscription_server(remote_data_client *client) { int len; char buf[260]; fqd_config *config; remote_client *parent; fq_rk key; fq_debug(FQ_DEBUG_CONN, "--> dss thread [%s]\n", client->mode == FQ_PROTO_DATA_MODE ? "client" : "peer"); if((len = fq_read_short_cmd(client->fd, sizeof(key.name), key.name)) < 0) return; if(len > (int)sizeof(key.name)) return; key.len = len; fq_rk_to_hex(buf, sizeof(buf), &key); fq_debug(FQ_DEBUG_CONN, "data conn w/ key:\n%s\n", buf); config = fqd_config_get(); parent = fqd_config_get_registered_client(config, &key); fqd_config_release(config); if(!parent) return; if(parent->data) return; ck_pr_cas_ptr(&parent->data, NULL, client); if(parent->data != client) { fq_debug(FQ_DEBUG_CONN, "%s dss double gang rejected\n", parent->pretty); return; } if(FQ_CLIENT_AUTH_DATA_ENABLED()) { fq_dtrace_remote_data_client_t dclient; DTRACE_PACK_DATA_CLIENT(&dclient, client); FQ_CLIENT_AUTH_DATA(&dclient); } fqd_remote_client_ref(parent); fqd_data_driver(parent); fq_clear_message_cleanup_stack(); fqd_remote_client_deref(parent); fq_debug(FQ_DEBUG_CONN, "<-- dss thread\n"); }
static int fqd_http_add_checkpoint(struct http_req *req) { fqd_config *config = fqd_config_get(); const char *cpname = get_ht_value(&req->query_params, "cpname"); const char *qname = get_ht_value(&req->query_params, "qname"); const char *chkptid = get_ht_value(&req->query_params, "chkptid"); fq_rk qn; fq_rk_from_str(&qn, qname); fqd_queue *queue = fqd_config_get_registered_queue(config, &qn); if (strcmp(cpname, "fq") == 0) { fqd_http_error_json(req->client, "'fq' is a reserved name, cannot be used for a checkpoint name"); req->close = 1; return 0; } if (queue == NULL) { fqd_http_error_json_f(req->client, "Cannot find registered queue '%s'", qname); req->close = 1; return 0; } /* do we really want this restriction? */ if (queue->permanent == false) { fqd_http_error_json(req->client, "Checkpoints on ephemeral queues not supported"); req->close = 1; return 0; } /* check points only supported on disk queue */ if (strcmp(queue->impl->name, "disk") != 0) { fqd_http_error_json(req->client, "Checkpoints on memory queues not supported"); req->close = 1; return 0; } /* validate chkptid format */ char ckid[48] = {0}; strncpy(ckid, chkptid, sizeof(ckid)-1); const char *log_string = ckid; char *sep = strchr(ckid, ':'); if (sep == NULL) { fqd_http_error_json(req->client, "'chkptid' must be of format: [0-9]*:[0-9]*"); req->close = 1; return 0; } sep[0] = '\0'; const char *marker_string = sep + 1; uint32_t log = atoi(log_string); uint32_t marker = atoi(marker_string); fq_msgid id = { .id.u32.p1 = log, .id.u32.p2 = marker }; int rv = queue->impl->add_checkpoint(queue->impl_data, cpname, &id); if (rv == -1) { fqd_http_error_json(req->client, "'chkptid' is out of range of the queue"); req->close = 1; return 0; } if (rv == -2) { fqd_http_error_json(req->client, "Failed to set checkpoint"); req->close = 1; return 0; } if (rv < 0) { fqd_http_error_json(req->client, "Unknown error"); req->close = 1; return 0; } fqd_http_success_json(req->client, "Checkpoint added"); req->close = 1; fq_debug(FQ_DEBUG_HTTP, ".on_complete -> add_checkpoint on [%s] for queue [%s] and id [%s]\n", cpname, qname, chkptid); return 0; } static int fqd_http_remove_checkpoint(struct http_req *req) { fqd_config *config = fqd_config_get(); const char *cpname = get_ht_value(&req->query_params, "cpname"); const char *qname = get_ht_value(&req->query_params, "qname"); fq_rk qn; fq_rk_from_str(&qn, qname); fqd_queue *queue = fqd_config_get_registered_queue(config, &qn); if (strcmp(cpname, "fq") == 0) { fqd_http_error_json(req->client, "'fq' is a reserved name, cannot be used for a checkpoint name"); req->close = 1; return 0; } if (queue == NULL) { fqd_http_error_json_f(req->client, "Cannot find registered queue '%s'", qname); req->close = 1; return 0; } int rv = queue->impl->remove_checkpoint(queue->impl_data, cpname); if (rv == -1) { fqd_http_error_json(req->client, "Checkpoint does not exist"); req->close = 1; return 0; } if (rv < 0) { fqd_http_error_json(req->client, "Unknown error"); req->close = 1; return 0; } fqd_http_success_json(req->client, "Checkpoint removed"); req->close = 1; fq_debug(FQ_DEBUG_HTTP, ".on_complete -> remove_checkpoint on [%s] for queue [%s]\n", cpname, qname); return 0; }