| 589 | } |
| 590 | |
| 591 | bool DataSourceRuntimeHost::cbPushMessage( |
| 592 | void* ctx, PJ_parser_binding_handle_t handle, int64_t timestamp_ns, PJ_message_data_fetcher_t fetch_message_data, |
| 593 | PJ_error_t* out_error) noexcept { |
| 594 | auto* self = static_cast<DataSourceRuntimeHost*>(ctx); |
| 595 | auto fetcher_owner = std::make_shared<FetcherOwner>(fetch_message_data, self->library_keepalive_); |
| 596 | |
| 597 | try { |
| 598 | auto it = self->parser_bindings_.find(handle.id); |
| 599 | if (it == self->parser_bindings_.end()) { |
| 600 | return self->fail(out_error, "invalid parser binding handle"); |
| 601 | } |
| 602 | auto& binding = it->second; |
| 603 | if (fetcher_owner->fetcher.fetchMessageData == nullptr) { |
| 604 | return self->fail(out_error, "message data fetcher is null"); |
| 605 | } |
| 606 | |
| 607 | // Object ingest policy only applies to parser bindings that actually |
| 608 | // classify as builtin objects. Scalar-only topics must stay eager so a |
| 609 | // broad default lazy policy cannot accidentally drop normal curves. |
| 610 | const bool is_object_topic = binding.object_topic_id.has_value(); |
| 611 | const auto policy = is_object_topic |
| 612 | ? self->policy_resolver_.resolve(self->source_id_, binding.topic_name, binding.object_kind) |
| 613 | : sdk::ObjectIngestPolicy::kEager; |
| 614 | |
| 615 | auto push_lazy_object = [&]() -> bool { |
| 616 | if (!is_object_topic) { |
| 617 | return true; |
| 618 | } |
| 619 | auto closure = makeLazyFetchClosure( |
| 620 | fetcher_owner, self->lazy_fetch_mutex_, |
| 621 | LazyFetchContext{ |
| 622 | .dataset_id = self->dataset_id_, |
| 623 | .object_topic_id = *binding.object_topic_id, |
| 624 | .source_id = self->source_id_, |
| 625 | .topic_name = binding.topic_name, |
| 626 | .timestamp_ns = timestamp_ns, |
| 627 | }); |
| 628 | if (auto status = |
| 629 | self->object_store_target_.load()->pushLazy(*binding.object_topic_id, timestamp_ns, std::move(closure)); |
| 630 | !status) { |
| 631 | return self->fail(out_error, ("ObjectStore.pushLazy failed: " + status.error()).c_str()); |
| 632 | } |
| 633 | return true; |
| 634 | }; |
| 635 | |
| 636 | if (policy == sdk::ObjectIngestPolicy::kPureLazy) { |
| 637 | return push_lazy_object(); |
| 638 | } |
| 639 | |
| 640 | PJ_payload_t payload{}; |
| 641 | bool fetched = false; |
| 642 | if (self->lazy_fetch_mutex_ != nullptr) { |
| 643 | std::lock_guard lock(*self->lazy_fetch_mutex_); |
| 644 | fetched = fetcher_owner->fetcher.fetchMessageData(fetcher_owner->fetcher.ctx, &payload, out_error); |
| 645 | } else { |
| 646 | fetched = fetcher_owner->fetcher.fetchMessageData(fetcher_owner->fetcher.ctx, &payload, out_error); |
| 647 | } |
| 648 | if (!fetched) { |
nothing calls this directly
no test coverage detected