Skip to content

Add support for EPICS Archiver Appliance#73

Open
rneswold wants to merge 26 commits intomainfrom
epics
Open

Add support for EPICS Archiver Appliance#73
rneswold wants to merge 26 commits intomainfrom
epics

Conversation

@rneswold
Copy link
Contributor

This PR adds support to the acceleratorData subscription to retrieve historical PV data from the Archiver Appliance.

The EPICS archiver sends one point at a time which is too slow for the
plotting app (the plotting app does a lot of work each time it gets a
packet of data.) This stream combinator will be used to buffer up a
large number of points to amortize the cost of updating the graph.
Since we're only going to ever instantiate one instance of this stream
type, there won't be code bloat by using generic parameters. However, I
can instantiate a max payload of 4, for instance, when writing unit
tests.
Due to inexperience, I was boxing each stream that was built. Each
combinator I created added another heap allocation and required a
dereference when pulling elements.

With the help of an AI, the stream APIs have been refactored to use
generics and `impl Stream<>` monomorphisms to create combined streams
that don't require heap allocations (besides any underlying vectors they
might use in their state.)
@rneswold rneswold requested review from beauremus and jacob-curley-fnal and removed request for beauremus January 14, 2026 22:33
@rneswold
Copy link
Contributor Author

Before merging, I need to make one more change.

@jacob-curley-fnal
Copy link
Contributor

I'll check back when the new changes are added, but here are my initial comments:

1.) I don't think I know enough about the context to give as good a review as I'd like on the strategies employed here. My gut reaction is I'm a little worried we're implementing a lot of our own streams, when there are some out-of-the-box options that would (I think) require less long-term maintenance, and certainly decrease cognitive overhead. Again, that is a naive reaction as I don't know all the details, so don't take that as me recommending we actually go that route. Only bringing it up in case there was a way to make use of them; I'm having good luck returning an instance of tokio_stream::wrappers::BroadcastStream for alarms data.

2.) Sort of related to 1.), but the poll_next loops are a little busy for my taste. It might be easier to make sense of the different cases if each branch called a helper function instead of being inlined. That way the concept of a "poll" becomes more high-level, easier to get a general sense of what's happening in each pass of the loop.

3.) Final thought, also building on 1.) and 2.), is more architectural. It looks like these changes are made to knit together different streams of data so we can shoot them back to clients as a single stream. That appears to involve a good amount of logic. Question I want to raise is, "How 'heavy' do we want extapi-acsys to be?" Corollary/implied question: "Would this logic make more sense in its own service or as part of some existing service, and the API service could just be a passthrough?" Only looking to spark the discussion over what our limits for extapi-acsys doing data massaging might look like

Overall, I've no objection to these changes going in! Just a reminder about the caveat from 1.), where I don't have insights into the motivations or context for these changes, so bear that in mind. Good stuff here!

Copy link
Contributor

@beauremus beauremus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @jacob-curley-fnal's comments.
I'm willing to approve, but this is so much that I'd like more eyes on it and ideally some high-level discussion about structures.
Let me know how you want to proceed @rneswold.

device: &str, start_time: f64, end_time: f64,
) -> Result<impl Stream<Item = global::DataReply> + Send + 'static + Unpin>
{
const BASE_URL: &str =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this temporary?
We want config like this defined in the K8s config and not code. Via a envar.
Also, no SSL.
Do both these get resolved when we move to gRPC?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would imagine that, when PIP-II gets closer to commissioning, they'll have a pool of archivers. This is mostly proof-of-concept. Most of the archived data is spotty and there aren't many PVs registered.

Eventually we'll have the production endpoint and I'll generalize the configuration for it.

.timestamp_opt(seconds, nanoseconds)
.earliest()
.unwrap_or_else(|| {
Utc.timestamp_millis_opt(0).unwrap() // Default to epoch start
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we log a warning in this case so we can more easily count the number of failures?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe? It's set-up to return Jan 1, 1970. Any client should be suspicious of that date. I'm not sure a log message improves anything.

}

#[instrument(name = "EPICS_ARCH", skip(device, start_time, end_time))]
async fn epics_archived_data(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize that the implementation of archived_data is quite different, but I expect them to share a function signature or a HistoricalData abstract class that they both implement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function returns a DataStream, just like our ACNET archived_data method does.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And the signatures are almost the same. The ACNET one uses the Context argument to obtain the DPM gRPC endpoint. The archiver does a single HTTP request so it doesn't need to preserve any state in Context<>.

task::{Context, Poll},
};
use tracing::warn;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is tough to grok.
I'm a bit concerned about absurd user historical requests bringing a pod to its knees due to buffering.

I think we could leverage concurrency and separation of concerns a bit more to make this simpler to understand. (concurrency == simpler 🤣)

Here's what I worked with copilot to mock up:

  1. Stream processing:
use tokio::sync::mpsc;
use tokio::task;

async fn process_archived_data(
    archived: impl Stream<Item = global::DataReply> + Send + 'static + Unpin,
    tx: mpsc::Sender<(i32, global::DataReply)>,
) {
    tokio::pin!(archived);
    while let Some(reply) = archived.next().await {
        if tx.send((reply.ref_id, reply)).await.is_err() {
            break; // Receiver dropped
        }
    }
}

async fn process_live_data(
    live: impl Stream<Item = global::DataReply> + Send + 'static + Unpin,
    tx: mpsc::Sender<(i32, global::DataReply)>,
) {
    tokio::pin!(live);
    while let Some(reply) = live.next().await {
        if tx.send((reply.ref_id, reply)).await.is_err() {
            break; // Receiver dropped
        }
    }
}
  1. Merging
async fn merge_streams(
    rx: mpsc::Receiver<(i32, global::DataReply)>,
) -> impl Stream<Item = global::DataReply> {
    tokio_stream::wrappers::ReceiverStream::new(rx)
        .filter_map(|(ref_id, reply)| async move {
            // Apply any filtering or ordering logic here
            Some(reply)
        })
}
  1. Execution
async fn data_merge(
    archived: impl Stream<Item = global::DataReply> + Send + 'static + Unpin,
    live: impl Stream<Item = global::DataReply> + Send + 'static + Unpin,
) -> impl Stream<Item = global::DataReply> {
    let (tx, rx) = mpsc::channel(100);

    // Spawn tasks for processing streams
    task::spawn(process_archived_data(archived, tx.clone()));
    task::spawn(process_live_data(live, tx));

    // Merge the streams
    merge_streams(rx).await
}

You've clearly thought about this a lot more than me. So don't let me hold this up, but I hope this plants some seeds.

Copy link
Contributor Author

@rneswold rneswold Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have used the combinators in futures::StreamExt if they met our needs, but they don't. For instance, your merge would have both streams write to the mpsc channel as the data comes in. My implementation returns the points in timestamp order so all the archive data gets returned first. Otherwise all our clients would need to sort by timestamp.

If I used .chain() to force one stream to finish before the other, then DPM could timeout if the archived data takes too long, so I wanted to pull and buffer DPM data so it didn't drop the subscription.

I'll try to clean some of this up, but I feel these data streams do stuff that the standard combinators don't. And the main reason is because:

  • We want to sort incoming data from multiple streams using the timestamp
  • DPM sends an empty array to indicate end-of-archived-data but doesn't close the stream
  • We're trying to return plot data in 15 Hz batches so that all channels get drawn together
  • Our stream of live data contains data from multiple devices, so we need to keep track of each's state

These are the sorts of problems the standard combinators don't solve.

@rneswold
Copy link
Contributor Author

I'm having good luck returning an instance of tokio_stream::wrappers::BroadcastStream for alarms data.

The gRPC API returns a Stream<> and the GraphQL crate wants a Stream<>. With these combinators, my GraphQL resolvers build a Stream<> that processes and transforms the data and hands the stream off to the webserver. When the subscription is cancelled, the Stream<> is dropped and all resources are automatically cleaned up.

Starting a background task to put stream entries into a mpsc::channel and then have another read the channel and forward to the GraphQL stream doesn't seem as simple and elegant as using these stream combinators. When a client cancels a subscription, how do you reliably clean-up the async tasks?

However, making the code easier to understand is a worthy goal.

I appreciate everyone's thoughts and comments!

@rneswold
Copy link
Contributor Author

I agree with @jacob-curley-fnal's comments.
I'm willing to approve, but this is so much that I'd like more eyes on it and ideally some high-level discussion about structures.
Let me know how you want to proceed @rneswold.

We could Zoom or meet in the Cooler on a day that Beau and I are onsite to go through it in more detail.

@github-actions
Copy link

Code Coverage Report - 1,487 of 3,627 lines covered ( ⛔ 41.00%)

src - 1,487 of 3,627 lines covered ( ⛔ 41.00%)

src/env_var - 21 of 33 lines covered ( ⛔ 63.64%)

src/env_var/mod.rs - 21 of 33 lines covered ( ⛔ 63.64%)

Uncovered lines: ⚠️ 19-20, 22-23, 26, 42-43, 45-47, 50, 56

src/g_rpc - 115 of 1,053 lines covered ( ⛔ 10.92%)

src/g_rpc/alarms_db - 81 of 88 lines covered ( ✅ 92.05%)

src/g_rpc/alarms_db/groups - 12 of 14 lines covered ( ⚠️ 85.71%)

src/g_rpc/alarms_db/groups/mod.rs - 12 of 14 lines covered ( ⚠️ 85.71%)

Uncovered lines: ⚠️ 13, 23

src/g_rpc/alarms_db/layouts - 4 of 5 lines covered ( ⚠️ 80.00%)

src/g_rpc/alarms_db/layouts/mod.rs - 4 of 5 lines covered ( ⚠️ 80.00%)

Uncovered lines: ⚠️ 10

src/g_rpc/alarms_db/mod.rs - 47 of 47 lines covered ( ✅ 100.00%)

Uncovered lines: ✅ None

src/g_rpc/alarms_db/timers - 18 of 22 lines covered ( ⚠️ 81.82%)

src/g_rpc/alarms_db/timers/mod.rs - 18 of 22 lines covered ( ⚠️ 81.82%)

Uncovered lines: ⚠️ 11, 19, 29, 37

src/g_rpc/clock - 0 of 12 lines covered ( ⛔ 0.00%)

src/g_rpc/clock/mod.rs - 0 of 12 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/devdb - 0 of 12 lines covered ( ⛔ 0.00%)

src/g_rpc/devdb/mod.rs - 0 of 12 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/dpm - 0 of 32 lines covered ( ⛔ 0.00%)

src/g_rpc/dpm/mod.rs - 0 of 32 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated - 34 of 796 lines covered ( ⛔ 4.27%)

src/g_rpc/generated/common.device.rs - 0 of 85 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/common.status.rs - 0 of 11 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/services.alarm_groups.rs - 7 of 95 lines covered ( ⛔ 7.37%)

Uncovered lines: ⚠️ 62, 72-95, 97-98, 104-107, 110-113, 118-121, 126-142, 144-146, 149-154, 157-168, 170-172, 175-180, 183-184

src/g_rpc/generated/services.alarm_timers.rs - 20 of 139 lines covered ( ⛔ 14.39%)

Uncovered lines: ⚠️ 86, 96-119, 121-122, 128-131, 134-137, 142-145, 150-163, 165-167, 170-173, 175-186, 188-190, 193-196, 198-209, 211-213, 216-219, 221-232, 234-236, 239-242, 244-245

src/g_rpc/generated/services.alarm_user_layouts.rs - 7 of 71 lines covered ( ⛔ 9.86%)

Uncovered lines: ⚠️ 37, 47-70, 72-73, 79-82, 85-88, 93-96, 101-114, 116-118, 121-126, 129-130

src/g_rpc/generated/services.clock_event.rs - 0 of 71 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/services.daq.rs - 0 of 128 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/services.tlg_placement.rs - 0 of 173 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/third_party.r#type.rs - 0 of 23 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/mod.rs - 0 of 36 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/tlg - 0 of 39 lines covered ( ⛔ 0.00%)

src/g_rpc/tlg/mod.rs - 0 of 39 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/wscan - 0 of 38 lines covered ( ⛔ 0.00%)

src/g_rpc/wscan/mod.rs - 0 of 38 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql - 1,250 of 2,391 lines covered ( ⛔ 52.28%)

src/graphql/acsys - 700 of 1,190 lines covered ( ⛔ 58.82%)

src/graphql/acsys/datastream - 525 of 610 lines covered ( ⚠️ 86.07%)

src/graphql/acsys/datastream/archivestream.rs - 0 of 20 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/acsys/datastream/datachannel.rs - 62 of 70 lines covered ( ✅ 88.57%)

Uncovered lines: ⚠️ 32-34, 36, 38-39, 82-83

src/graphql/acsys/datastream/datamerge.rs - 143 of 164 lines covered ( ⚠️ 87.20%)

Uncovered lines: ⚠️ 98, 103-104, 106-107, 121, 152, 161, 166-167, 169-170, 180-181, 184, 186, 194-197, 202

src/graphql/acsys/datastream/endondate.rs - 87 of 90 lines covered ( ✅ 96.67%)

Uncovered lines: ⚠️ 35, 72, 86

src/graphql/acsys/datastream/filterdupes.rs - 82 of 85 lines covered ( ✅ 96.47%)

Uncovered lines: ⚠️ 53, 81-82

src/graphql/acsys/datastream/groupscalars.rs - 151 of 165 lines covered ( ✅ 91.52%)

Uncovered lines: ⚠️ 74-77, 79-82, 101-102, 160-162, 166

src/graphql/acsys/datastream/mod.rs - 0 of 16 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/acsys/mod.rs - 132 of 484 lines covered ( ⛔ 27.27%)

Uncovered lines: ⚠️ 24-26, 33-39, 44-65, 67-77, 79, 81-94, 97, 115-122, 127, 169, 232-242, 277, 313-316, 335, 414, 417-425, 427-428, 430-433, 435-439, 441-443, 446-449, 451, 454-458, 466-469, 474-475, 479-485, 487, 489-492, 494-496, 498, 500-501, 503, 506-509, 537, 542-544, 584, 587-601, 603-605, 608-618, 623, 625-635, 640-656, 659-660, 662, 664, 666-667, 669, 671, 715-718, 725-733, 735-737, 748-749, 751, 753-762, 765, 820, 853-854, 867-900, 910-912, 927-929, 931, 933-934, 982-985, 995, 1005-1052, 1058, 1062, 1078

src/graphql/acsys/plotconfigdb.rs - 43 of 94 lines covered ( ⛔ 45.74%)

Uncovered lines: ⚠️ 24-26, 29, 33, 35, 37, 39-43, 45-47, 59-62, 68-69, 71, 77-79, 114-116, 118-122, 124-128, 130-134, 136-140, 142-144

src/graphql/acsys/types.rs - 0 of 2 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/alarms - 443 of 475 lines covered ( ✅ 93.26%)

src/graphql/alarms/mod.rs - 254 of 286 lines covered ( ✅ 88.81%)

Uncovered lines: ⚠️ 42, 56, 77, 91-97, 111-117, 125-131, 139, 153-159

src/graphql/alarms/types.rs - 122 of 122 lines covered ( ✅ 100.00%)

Uncovered lines: ✅ None

src/graphql/alarms/utils.rs - 67 of 67 lines covered ( ✅ 100.00%)

Uncovered lines: ✅ None

src/graphql/bbm - 0 of 116 lines covered ( ⛔ 0.00%)

src/graphql/bbm/mod.rs - 0 of 31 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/bbm/types.rs - 0 of 85 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/devdb - 0 of 104 lines covered ( ⛔ 0.00%)

src/graphql/devdb/mod.rs - 0 of 97 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/devdb/types.rs - 0 of 7 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/faas - 0 of 80 lines covered ( ⛔ 0.00%)

src/graphql/faas/mod.rs - 0 of 80 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/mod.rs - 97 of 217 lines covered ( ⛔ 44.70%)

Uncovered lines: ⚠️ 52-72, 110, 114-117, 119-132, 134-135, 140, 143-145, 147-151, 153-157, 159, 164, 167-170, 172-176, 178-182, 184, 186, 189-191, 193-197, 199-201, 203, 205, 208-210, 212-216, 218-220, 222, 227, 231-234, 236, 238-243, 245-250, 252-253, 288

src/graphql/scanner - 0 of 41 lines covered ( ⛔ 0.00%)

src/graphql/scanner/mod.rs - 0 of 16 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/scanner/types.rs - 0 of 25 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/tlg - 0 of 48 lines covered ( ⛔ 0.00%)

src/graphql/tlg/mod.rs - 0 of 25 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/tlg/types.rs - 0 of 23 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/types.rs - 10 of 120 lines covered ( ⛔ 8.33%)

Uncovered lines: ⚠️ 23-25, 27-29, 36-40, 42-44, 46-53, 187, 206-207, 210, 216-218, 221, 226-228, 232, 236-240, 245, 248-250, 256, 258-260, 267-272, 280-282, 284, 293-296, 298-301, 303-307, 309-312, 314-321, 323, 329-332, 334-337, 339-348, 350-357, 359

src/main.rs - 0 of 12 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/pubsub - 101 of 138 lines covered ( ⛔ 73.19%)

src/pubsub/mod.rs - 101 of 138 lines covered ( ⛔ 73.19%)

Uncovered lines: ⚠️ 42-51, 53, 55-56, 58, 60, 104-105, 107-109, 131-133, 152, 154, 156-159, 161-164, 167-169, 173

This should make it reach 100% coverage.
@github-actions
Copy link

Code Coverage Report - 1,555 of 3,693 lines covered ( ⛔ 42.11%)

src - 1,555 of 3,693 lines covered ( ⛔ 42.11%)

src/env_var - 21 of 33 lines covered ( ⛔ 63.64%)

src/env_var/mod.rs - 21 of 33 lines covered ( ⛔ 63.64%)

Uncovered lines: ⚠️ 19-20, 22-23, 26, 42-43, 45-47, 50, 56

src/g_rpc - 115 of 1,053 lines covered ( ⛔ 10.92%)

src/g_rpc/alarms_db - 81 of 88 lines covered ( ✅ 92.05%)

src/g_rpc/alarms_db/groups - 12 of 14 lines covered ( ⚠️ 85.71%)

src/g_rpc/alarms_db/groups/mod.rs - 12 of 14 lines covered ( ⚠️ 85.71%)

Uncovered lines: ⚠️ 13, 23

src/g_rpc/alarms_db/layouts - 4 of 5 lines covered ( ⚠️ 80.00%)

src/g_rpc/alarms_db/layouts/mod.rs - 4 of 5 lines covered ( ⚠️ 80.00%)

Uncovered lines: ⚠️ 10

src/g_rpc/alarms_db/mod.rs - 47 of 47 lines covered ( ✅ 100.00%)

Uncovered lines: ✅ None

src/g_rpc/alarms_db/timers - 18 of 22 lines covered ( ⚠️ 81.82%)

src/g_rpc/alarms_db/timers/mod.rs - 18 of 22 lines covered ( ⚠️ 81.82%)

Uncovered lines: ⚠️ 11, 19, 29, 37

src/g_rpc/clock - 0 of 12 lines covered ( ⛔ 0.00%)

src/g_rpc/clock/mod.rs - 0 of 12 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/devdb - 0 of 12 lines covered ( ⛔ 0.00%)

src/g_rpc/devdb/mod.rs - 0 of 12 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/dpm - 0 of 32 lines covered ( ⛔ 0.00%)

src/g_rpc/dpm/mod.rs - 0 of 32 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated - 34 of 796 lines covered ( ⛔ 4.27%)

src/g_rpc/generated/common.device.rs - 0 of 85 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/common.status.rs - 0 of 11 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/services.alarm_groups.rs - 7 of 95 lines covered ( ⛔ 7.37%)

Uncovered lines: ⚠️ 62, 72-95, 97-98, 104-107, 110-113, 118-121, 126-142, 144-146, 149-154, 157-168, 170-172, 175-180, 183-184

src/g_rpc/generated/services.alarm_timers.rs - 20 of 139 lines covered ( ⛔ 14.39%)

Uncovered lines: ⚠️ 86, 96-119, 121-122, 128-131, 134-137, 142-145, 150-163, 165-167, 170-173, 175-186, 188-190, 193-196, 198-209, 211-213, 216-219, 221-232, 234-236, 239-242, 244-245

src/g_rpc/generated/services.alarm_user_layouts.rs - 7 of 71 lines covered ( ⛔ 9.86%)

Uncovered lines: ⚠️ 37, 47-70, 72-73, 79-82, 85-88, 93-96, 101-114, 116-118, 121-126, 129-130

src/g_rpc/generated/services.clock_event.rs - 0 of 71 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/services.daq.rs - 0 of 128 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/services.tlg_placement.rs - 0 of 173 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/third_party.r#type.rs - 0 of 23 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/mod.rs - 0 of 36 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/tlg - 0 of 39 lines covered ( ⛔ 0.00%)

src/g_rpc/tlg/mod.rs - 0 of 39 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/wscan - 0 of 38 lines covered ( ⛔ 0.00%)

src/g_rpc/wscan/mod.rs - 0 of 38 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql - 1,318 of 2,457 lines covered ( ⛔ 53.64%)

src/graphql/acsys - 768 of 1,256 lines covered ( ⛔ 61.15%)

src/graphql/acsys/datastream - 593 of 676 lines covered ( ⚠️ 87.72%)

src/graphql/acsys/datastream/archivestream.rs - 0 of 20 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/acsys/datastream/datachannel.rs - 62 of 70 lines covered ( ✅ 88.57%)

Uncovered lines: ⚠️ 32-34, 36, 38-39, 82-83

src/graphql/acsys/datastream/datamerge.rs - 143 of 164 lines covered ( ⚠️ 87.20%)

Uncovered lines: ⚠️ 98, 103-104, 106-107, 121, 152, 161, 166-167, 169-170, 180-181, 184, 186, 194-197, 202

src/graphql/acsys/datastream/endondate.rs - 155 of 156 lines covered ( ✅ 99.36%)

Uncovered lines: ⚠️ 72

src/graphql/acsys/datastream/filterdupes.rs - 82 of 85 lines covered ( ✅ 96.47%)

Uncovered lines: ⚠️ 53, 81-82

src/graphql/acsys/datastream/groupscalars.rs - 151 of 165 lines covered ( ✅ 91.52%)

Uncovered lines: ⚠️ 74-77, 79-82, 101-102, 160-162, 166

src/graphql/acsys/datastream/mod.rs - 0 of 16 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/acsys/mod.rs - 132 of 484 lines covered ( ⛔ 27.27%)

Uncovered lines: ⚠️ 24-26, 33-39, 44-65, 67-77, 79, 81-94, 97, 115-122, 127, 169, 232-242, 277, 313-316, 335, 414, 417-425, 427-428, 430-433, 435-439, 441-443, 446-449, 451, 454-458, 466-469, 474-475, 479-485, 487, 489-492, 494-496, 498, 500-501, 503, 506-509, 537, 542-544, 584, 587-601, 603-605, 608-618, 623, 625-635, 640-656, 659-660, 662, 664, 666-667, 669, 671, 715-718, 725-733, 735-737, 748-749, 751, 753-762, 765, 820, 853-854, 867-900, 910-912, 927-929, 931, 933-934, 982-985, 995, 1005-1052, 1058, 1062, 1078

src/graphql/acsys/plotconfigdb.rs - 43 of 94 lines covered ( ⛔ 45.74%)

Uncovered lines: ⚠️ 24-26, 29, 33, 35, 37, 39-43, 45-47, 59-62, 68-69, 71, 77-79, 114-116, 118-122, 124-128, 130-134, 136-140, 142-144

src/graphql/acsys/types.rs - 0 of 2 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/alarms - 443 of 475 lines covered ( ✅ 93.26%)

src/graphql/alarms/mod.rs - 254 of 286 lines covered ( ✅ 88.81%)

Uncovered lines: ⚠️ 42, 56, 77, 91-97, 111-117, 125-131, 139, 153-159

src/graphql/alarms/types.rs - 122 of 122 lines covered ( ✅ 100.00%)

Uncovered lines: ✅ None

src/graphql/alarms/utils.rs - 67 of 67 lines covered ( ✅ 100.00%)

Uncovered lines: ✅ None

src/graphql/bbm - 0 of 116 lines covered ( ⛔ 0.00%)

src/graphql/bbm/mod.rs - 0 of 31 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/bbm/types.rs - 0 of 85 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/devdb - 0 of 104 lines covered ( ⛔ 0.00%)

src/graphql/devdb/mod.rs - 0 of 97 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/devdb/types.rs - 0 of 7 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/faas - 0 of 80 lines covered ( ⛔ 0.00%)

src/graphql/faas/mod.rs - 0 of 80 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/mod.rs - 97 of 217 lines covered ( ⛔ 44.70%)

Uncovered lines: ⚠️ 52-72, 110, 114-117, 119-132, 134-135, 140, 143-145, 147-151, 153-157, 159, 164, 167-170, 172-176, 178-182, 184, 186, 189-191, 193-197, 199-201, 203, 205, 208-210, 212-216, 218-220, 222, 227, 231-234, 236, 238-243, 245-250, 252-253, 288

src/graphql/scanner - 0 of 41 lines covered ( ⛔ 0.00%)

src/graphql/scanner/mod.rs - 0 of 16 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/scanner/types.rs - 0 of 25 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/tlg - 0 of 48 lines covered ( ⛔ 0.00%)

src/graphql/tlg/mod.rs - 0 of 25 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/tlg/types.rs - 0 of 23 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/types.rs - 10 of 120 lines covered ( ⛔ 8.33%)

Uncovered lines: ⚠️ 23-25, 27-29, 36-40, 42-44, 46-53, 187, 206-207, 210, 216-218, 221, 226-228, 232, 236-240, 245, 248-250, 256, 258-260, 267-272, 280-282, 284, 293-296, 298-301, 303-307, 309-312, 314-321, 323, 329-332, 334-337, 339-348, 350-357, 359

src/main.rs - 0 of 12 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/pubsub - 101 of 138 lines covered ( ⛔ 73.19%)

src/pubsub/mod.rs - 101 of 138 lines covered ( ⛔ 73.19%)

Uncovered lines: ⚠️ 42-51, 53, 55-56, 58, 60, 104-105, 107-109, 131-133, 152, 154, 156-159, 161-164, 167-169, 173

@github-actions
Copy link

Code Coverage Report - 1,564 of 3,700 lines covered ( ⛔ 42.27%)

src - 1,564 of 3,700 lines covered ( ⛔ 42.27%)

src/env_var - 21 of 33 lines covered ( ⛔ 63.64%)

src/env_var/mod.rs - 21 of 33 lines covered ( ⛔ 63.64%)

Uncovered lines: ⚠️ 19-20, 22-23, 26, 42-43, 45-47, 50, 56

src/g_rpc - 115 of 1,053 lines covered ( ⛔ 10.92%)

src/g_rpc/alarms_db - 81 of 88 lines covered ( ✅ 92.05%)

src/g_rpc/alarms_db/groups - 12 of 14 lines covered ( ⚠️ 85.71%)

src/g_rpc/alarms_db/groups/mod.rs - 12 of 14 lines covered ( ⚠️ 85.71%)

Uncovered lines: ⚠️ 13, 23

src/g_rpc/alarms_db/layouts - 4 of 5 lines covered ( ⚠️ 80.00%)

src/g_rpc/alarms_db/layouts/mod.rs - 4 of 5 lines covered ( ⚠️ 80.00%)

Uncovered lines: ⚠️ 10

src/g_rpc/alarms_db/mod.rs - 47 of 47 lines covered ( ✅ 100.00%)

Uncovered lines: ✅ None

src/g_rpc/alarms_db/timers - 18 of 22 lines covered ( ⚠️ 81.82%)

src/g_rpc/alarms_db/timers/mod.rs - 18 of 22 lines covered ( ⚠️ 81.82%)

Uncovered lines: ⚠️ 11, 19, 29, 37

src/g_rpc/clock - 0 of 12 lines covered ( ⛔ 0.00%)

src/g_rpc/clock/mod.rs - 0 of 12 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/devdb - 0 of 12 lines covered ( ⛔ 0.00%)

src/g_rpc/devdb/mod.rs - 0 of 12 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/dpm - 0 of 32 lines covered ( ⛔ 0.00%)

src/g_rpc/dpm/mod.rs - 0 of 32 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated - 34 of 796 lines covered ( ⛔ 4.27%)

src/g_rpc/generated/common.device.rs - 0 of 85 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/common.status.rs - 0 of 11 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/services.alarm_groups.rs - 7 of 95 lines covered ( ⛔ 7.37%)

Uncovered lines: ⚠️ 62, 72-95, 97-98, 104-107, 110-113, 118-121, 126-142, 144-146, 149-154, 157-168, 170-172, 175-180, 183-184

src/g_rpc/generated/services.alarm_timers.rs - 20 of 139 lines covered ( ⛔ 14.39%)

Uncovered lines: ⚠️ 86, 96-119, 121-122, 128-131, 134-137, 142-145, 150-163, 165-167, 170-173, 175-186, 188-190, 193-196, 198-209, 211-213, 216-219, 221-232, 234-236, 239-242, 244-245

src/g_rpc/generated/services.alarm_user_layouts.rs - 7 of 71 lines covered ( ⛔ 9.86%)

Uncovered lines: ⚠️ 37, 47-70, 72-73, 79-82, 85-88, 93-96, 101-114, 116-118, 121-126, 129-130

src/g_rpc/generated/services.clock_event.rs - 0 of 71 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/services.daq.rs - 0 of 128 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/services.tlg_placement.rs - 0 of 173 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/third_party.r#type.rs - 0 of 23 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/mod.rs - 0 of 36 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/tlg - 0 of 39 lines covered ( ⛔ 0.00%)

src/g_rpc/tlg/mod.rs - 0 of 39 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/wscan - 0 of 38 lines covered ( ⛔ 0.00%)

src/g_rpc/wscan/mod.rs - 0 of 38 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql - 1,327 of 2,464 lines covered ( ⛔ 53.86%)

src/graphql/acsys - 777 of 1,263 lines covered ( ⛔ 61.52%)

src/graphql/acsys/datastream - 602 of 683 lines covered ( ✅ 88.14%)

src/graphql/acsys/datastream/archivestream.rs - 0 of 20 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/acsys/datastream/datachannel.rs - 62 of 70 lines covered ( ✅ 88.57%)

Uncovered lines: ⚠️ 32-34, 36, 38-39, 82-83

src/graphql/acsys/datastream/datamerge.rs - 143 of 164 lines covered ( ⚠️ 87.20%)

Uncovered lines: ⚠️ 98, 103-104, 106-107, 121, 152, 161, 166-167, 169-170, 180-181, 184, 186, 194-197, 202

src/graphql/acsys/datastream/endondate.rs - 155 of 156 lines covered ( ✅ 99.36%)

Uncovered lines: ⚠️ 72

src/graphql/acsys/datastream/filterdupes.rs - 91 of 92 lines covered ( ✅ 98.91%)

Uncovered lines: ⚠️ 79

src/graphql/acsys/datastream/groupscalars.rs - 151 of 165 lines covered ( ✅ 91.52%)

Uncovered lines: ⚠️ 74-77, 79-82, 101-102, 160-162, 166

src/graphql/acsys/datastream/mod.rs - 0 of 16 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/acsys/mod.rs - 132 of 484 lines covered ( ⛔ 27.27%)

Uncovered lines: ⚠️ 24-26, 33-39, 44-65, 67-77, 79, 81-94, 97, 115-122, 127, 169, 232-242, 277, 313-316, 335, 414, 417-425, 427-428, 430-433, 435-439, 441-443, 446-449, 451, 454-458, 466-469, 474-475, 479-485, 487, 489-492, 494-496, 498, 500-501, 503, 506-509, 537, 542-544, 584, 587-601, 603-605, 608-618, 623, 625-635, 640-656, 659-660, 662, 664, 666-667, 669, 671, 715-718, 725-733, 735-737, 748-749, 751, 753-762, 765, 820, 853-854, 867-900, 910-912, 927-929, 931, 933-934, 982-985, 995, 1005-1052, 1058, 1062, 1078

src/graphql/acsys/plotconfigdb.rs - 43 of 94 lines covered ( ⛔ 45.74%)

Uncovered lines: ⚠️ 24-26, 29, 33, 35, 37, 39-43, 45-47, 59-62, 68-69, 71, 77-79, 114-116, 118-122, 124-128, 130-134, 136-140, 142-144

src/graphql/acsys/types.rs - 0 of 2 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/alarms - 443 of 475 lines covered ( ✅ 93.26%)

src/graphql/alarms/mod.rs - 254 of 286 lines covered ( ✅ 88.81%)

Uncovered lines: ⚠️ 42, 56, 77, 91-97, 111-117, 125-131, 139, 153-159

src/graphql/alarms/types.rs - 122 of 122 lines covered ( ✅ 100.00%)

Uncovered lines: ✅ None

src/graphql/alarms/utils.rs - 67 of 67 lines covered ( ✅ 100.00%)

Uncovered lines: ✅ None

src/graphql/bbm - 0 of 116 lines covered ( ⛔ 0.00%)

src/graphql/bbm/mod.rs - 0 of 31 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/bbm/types.rs - 0 of 85 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/devdb - 0 of 104 lines covered ( ⛔ 0.00%)

src/graphql/devdb/mod.rs - 0 of 97 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/devdb/types.rs - 0 of 7 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/faas - 0 of 80 lines covered ( ⛔ 0.00%)

src/graphql/faas/mod.rs - 0 of 80 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/mod.rs - 97 of 217 lines covered ( ⛔ 44.70%)

Uncovered lines: ⚠️ 52-72, 110, 114-117, 119-132, 134-135, 140, 143-145, 147-151, 153-157, 159, 164, 167-170, 172-176, 178-182, 184, 186, 189-191, 193-197, 199-201, 203, 205, 208-210, 212-216, 218-220, 222, 227, 231-234, 236, 238-243, 245-250, 252-253, 288

src/graphql/scanner - 0 of 41 lines covered ( ⛔ 0.00%)

src/graphql/scanner/mod.rs - 0 of 16 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/scanner/types.rs - 0 of 25 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/tlg - 0 of 48 lines covered ( ⛔ 0.00%)

src/graphql/tlg/mod.rs - 0 of 25 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/tlg/types.rs - 0 of 23 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/types.rs - 10 of 120 lines covered ( ⛔ 8.33%)

Uncovered lines: ⚠️ 23-25, 27-29, 36-40, 42-44, 46-53, 187, 206-207, 210, 216-218, 221, 226-228, 232, 236-240, 245, 248-250, 256, 258-260, 267-272, 280-282, 284, 293-296, 298-301, 303-307, 309-312, 314-321, 323, 329-332, 334-337, 339-348, 350-357, 359

src/main.rs - 0 of 12 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/pubsub - 101 of 138 lines covered ( ⛔ 73.19%)

src/pubsub/mod.rs - 101 of 138 lines covered ( ⛔ 73.19%)

Uncovered lines: ⚠️ 42-51, 53, 55-56, 58, 60, 104-105, 107-109, 131-133, 152, 154, 156-159, 161-164, 167-169, 173

@github-actions
Copy link

Code Coverage Report - 1,565 of 3,700 lines covered ( ⛔ 42.30%)

src - 1,565 of 3,700 lines covered ( ⛔ 42.30%)

src/env_var - 21 of 33 lines covered ( ⛔ 63.64%)

src/env_var/mod.rs - 21 of 33 lines covered ( ⛔ 63.64%)

Uncovered lines: ⚠️ 19-20, 22-23, 26, 42-43, 45-47, 50, 56

src/g_rpc - 115 of 1,053 lines covered ( ⛔ 10.92%)

src/g_rpc/alarms_db - 81 of 88 lines covered ( ✅ 92.05%)

src/g_rpc/alarms_db/groups - 12 of 14 lines covered ( ⚠️ 85.71%)

src/g_rpc/alarms_db/groups/mod.rs - 12 of 14 lines covered ( ⚠️ 85.71%)

Uncovered lines: ⚠️ 13, 23

src/g_rpc/alarms_db/layouts - 4 of 5 lines covered ( ⚠️ 80.00%)

src/g_rpc/alarms_db/layouts/mod.rs - 4 of 5 lines covered ( ⚠️ 80.00%)

Uncovered lines: ⚠️ 10

src/g_rpc/alarms_db/mod.rs - 47 of 47 lines covered ( ✅ 100.00%)

Uncovered lines: ✅ None

src/g_rpc/alarms_db/timers - 18 of 22 lines covered ( ⚠️ 81.82%)

src/g_rpc/alarms_db/timers/mod.rs - 18 of 22 lines covered ( ⚠️ 81.82%)

Uncovered lines: ⚠️ 11, 19, 29, 37

src/g_rpc/clock - 0 of 12 lines covered ( ⛔ 0.00%)

src/g_rpc/clock/mod.rs - 0 of 12 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/devdb - 0 of 12 lines covered ( ⛔ 0.00%)

src/g_rpc/devdb/mod.rs - 0 of 12 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/dpm - 0 of 32 lines covered ( ⛔ 0.00%)

src/g_rpc/dpm/mod.rs - 0 of 32 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated - 34 of 796 lines covered ( ⛔ 4.27%)

src/g_rpc/generated/common.device.rs - 0 of 85 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/common.status.rs - 0 of 11 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/services.alarm_groups.rs - 7 of 95 lines covered ( ⛔ 7.37%)

Uncovered lines: ⚠️ 62, 72-95, 97-98, 104-107, 110-113, 118-121, 126-142, 144-146, 149-154, 157-168, 170-172, 175-180, 183-184

src/g_rpc/generated/services.alarm_timers.rs - 20 of 139 lines covered ( ⛔ 14.39%)

Uncovered lines: ⚠️ 86, 96-119, 121-122, 128-131, 134-137, 142-145, 150-163, 165-167, 170-173, 175-186, 188-190, 193-196, 198-209, 211-213, 216-219, 221-232, 234-236, 239-242, 244-245

src/g_rpc/generated/services.alarm_user_layouts.rs - 7 of 71 lines covered ( ⛔ 9.86%)

Uncovered lines: ⚠️ 37, 47-70, 72-73, 79-82, 85-88, 93-96, 101-114, 116-118, 121-126, 129-130

src/g_rpc/generated/services.clock_event.rs - 0 of 71 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/services.daq.rs - 0 of 128 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/services.tlg_placement.rs - 0 of 173 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/generated/third_party.r#type.rs - 0 of 23 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/mod.rs - 0 of 36 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/tlg - 0 of 39 lines covered ( ⛔ 0.00%)

src/g_rpc/tlg/mod.rs - 0 of 39 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/g_rpc/wscan - 0 of 38 lines covered ( ⛔ 0.00%)

src/g_rpc/wscan/mod.rs - 0 of 38 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql - 1,328 of 2,464 lines covered ( ⛔ 53.90%)

src/graphql/acsys - 778 of 1,263 lines covered ( ⛔ 61.60%)

src/graphql/acsys/datastream - 603 of 683 lines covered ( ✅ 88.29%)

src/graphql/acsys/datastream/archivestream.rs - 0 of 20 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/acsys/datastream/datachannel.rs - 62 of 70 lines covered ( ✅ 88.57%)

Uncovered lines: ⚠️ 32-34, 36, 38-39, 82-83

src/graphql/acsys/datastream/datamerge.rs - 143 of 164 lines covered ( ⚠️ 87.20%)

Uncovered lines: ⚠️ 98, 103-104, 106-107, 121, 152, 161, 166-167, 169-170, 180-181, 184, 186, 194-197, 202

src/graphql/acsys/datastream/endondate.rs - 155 of 156 lines covered ( ✅ 99.36%)

Uncovered lines: ⚠️ 72

src/graphql/acsys/datastream/filterdupes.rs - 92 of 92 lines covered ( ✅ 100.00%)

Uncovered lines: ✅ None

src/graphql/acsys/datastream/groupscalars.rs - 151 of 165 lines covered ( ✅ 91.52%)

Uncovered lines: ⚠️ 74-77, 79-82, 101-102, 160-162, 166

src/graphql/acsys/datastream/mod.rs - 0 of 16 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/acsys/mod.rs - 132 of 484 lines covered ( ⛔ 27.27%)

Uncovered lines: ⚠️ 24-26, 33-39, 44-65, 67-77, 79, 81-94, 97, 115-122, 127, 169, 232-242, 277, 313-316, 335, 414, 417-425, 427-428, 430-433, 435-439, 441-443, 446-449, 451, 454-458, 466-469, 474-475, 479-485, 487, 489-492, 494-496, 498, 500-501, 503, 506-509, 537, 542-544, 584, 587-601, 603-605, 608-618, 623, 625-635, 640-656, 659-660, 662, 664, 666-667, 669, 671, 715-718, 725-733, 735-737, 748-749, 751, 753-762, 765, 820, 853-854, 867-900, 910-912, 927-929, 931, 933-934, 982-985, 995, 1005-1052, 1058, 1062, 1078

src/graphql/acsys/plotconfigdb.rs - 43 of 94 lines covered ( ⛔ 45.74%)

Uncovered lines: ⚠️ 24-26, 29, 33, 35, 37, 39-43, 45-47, 59-62, 68-69, 71, 77-79, 114-116, 118-122, 124-128, 130-134, 136-140, 142-144

src/graphql/acsys/types.rs - 0 of 2 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/alarms - 443 of 475 lines covered ( ✅ 93.26%)

src/graphql/alarms/mod.rs - 254 of 286 lines covered ( ✅ 88.81%)

Uncovered lines: ⚠️ 42, 56, 77, 91-97, 111-117, 125-131, 139, 153-159

src/graphql/alarms/types.rs - 122 of 122 lines covered ( ✅ 100.00%)

Uncovered lines: ✅ None

src/graphql/alarms/utils.rs - 67 of 67 lines covered ( ✅ 100.00%)

Uncovered lines: ✅ None

src/graphql/bbm - 0 of 116 lines covered ( ⛔ 0.00%)

src/graphql/bbm/mod.rs - 0 of 31 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/bbm/types.rs - 0 of 85 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/devdb - 0 of 104 lines covered ( ⛔ 0.00%)

src/graphql/devdb/mod.rs - 0 of 97 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/devdb/types.rs - 0 of 7 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/faas - 0 of 80 lines covered ( ⛔ 0.00%)

src/graphql/faas/mod.rs - 0 of 80 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/mod.rs - 97 of 217 lines covered ( ⛔ 44.70%)

Uncovered lines: ⚠️ 52-72, 110, 114-117, 119-132, 134-135, 140, 143-145, 147-151, 153-157, 159, 164, 167-170, 172-176, 178-182, 184, 186, 189-191, 193-197, 199-201, 203, 205, 208-210, 212-216, 218-220, 222, 227, 231-234, 236, 238-243, 245-250, 252-253, 288

src/graphql/scanner - 0 of 41 lines covered ( ⛔ 0.00%)

src/graphql/scanner/mod.rs - 0 of 16 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/scanner/types.rs - 0 of 25 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/tlg - 0 of 48 lines covered ( ⛔ 0.00%)

src/graphql/tlg/mod.rs - 0 of 25 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/tlg/types.rs - 0 of 23 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/graphql/types.rs - 10 of 120 lines covered ( ⛔ 8.33%)

Uncovered lines: ⚠️ 23-25, 27-29, 36-40, 42-44, 46-53, 187, 206-207, 210, 216-218, 221, 226-228, 232, 236-240, 245, 248-250, 256, 258-260, 267-272, 280-282, 284, 293-296, 298-301, 303-307, 309-312, 314-321, 323, 329-332, 334-337, 339-348, 350-357, 359

src/main.rs - 0 of 12 lines covered ( ⛔ 0.00%)

Uncovered lines: ⛔ This file is missing coverage.

src/pubsub - 101 of 138 lines covered ( ⛔ 73.19%)

src/pubsub/mod.rs - 101 of 138 lines covered ( ⛔ 73.19%)

Uncovered lines: ⚠️ 42-51, 53, 55-56, 58, 60, 104-105, 107-109, 131-133, 152, 154, 156-159, 161-164, 167-169, 173

This adds a 2 second timeout for connecting to the clock service. Before
this, if the clock service wasn't running, it would take a long time
before the request would time-out.
The EPICS archiver appliance uses HTTP 1.1 to return the data.
Initially, the GraphQL resolver had to wait for the whole document to be
delivered before it could parsed and sent on to the client.

The appliance returns the document in chunked format. With the help of
AI, this commit is able to do a little hackery with the incoming stream
of chunks. It is able to parse the data returns as they arrive which
greatly speeds up the plotting of the data.
@rneswold
Copy link
Contributor Author

rneswold commented Jan 30, 2026

@cnlklink and I are documenting some minor issues with the latest commit so there will probably be a future commit to fix them. I also want to add a few unit tests for the new code.

So it's not ready to merge, yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants