+static grpc::Status Process(grpc::ServerContext *ctx,
+ DispatchValuesRequest request, DispatchValuesReply *reply)
+{
+ value_list_t vl = VALUE_LIST_INIT;
+ auto status = unmarshal_value_list(request.values(), &vl);
+ if (!status.ok())
+ return status;
+
+ if (plugin_dispatch_values(&vl))
+ status = grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to enqueue values for writing"));
+ return status;
+} /* Process(): DispatchValues */
+
+static grpc::Status Process(grpc::ServerContext *ctx,
+ QueryValuesRequest request, QueryValuesReply *reply)
+{
+ uc_iter_t *iter;
+ char *name = NULL;
+
+ value_list_t matcher;
+ auto status = unmarshal_ident(request.identifier(), &matcher, false);
+ if (!status.ok())
+ return status;
+
+ if ((iter = uc_get_iterator()) == NULL) {
+ return grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to query values: cannot create iterator"));
+ }
+
+ status = grpc::Status::OK;
+ while (uc_iterator_next(iter, &name) == 0) {
+ value_list_t res;
+ if (parse_identifier_vl(name, &res) != 0) {
+ status = grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to parse identifier"));
+ break;
+ }
+
+ if (!ident_matches(&res, &matcher))
+ continue;
+
+ if (uc_iterator_get_time(iter, &res.time) < 0) {
+ status = grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to retrieve value timestamp"));
+ break;
+ }
+ if (uc_iterator_get_interval(iter, &res.interval) < 0) {
+ status = grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to retrieve value interval"));
+ break;
+ }
+ if (uc_iterator_get_values(iter, &res.values, &res.values_len) < 0) {
+ status = grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to retrieve values"));
+ break;
+ }
+
+ auto vl = reply->add_values();
+ status = marshal_value_list(&res, vl);
+ free(res.values);
+ if (!status.ok())
+ break;
+ }
+
+ uc_iterator_destroy(iter);
+
+ return status;
+} /* Process(): QueryValues */
+