Closed Bug 1623304 Opened 4 years ago Closed 4 years ago

Ping upload using the Firefox network stack

Categories

(Toolkit :: Telemetry, task, P3)

task
Points:
3

Tracking

()

RESOLVED FIXED
mozilla79
Tracking Status
firefox79 --- fixed

People

(Reporter: janerik, Assigned: chutten)

References

Details

(Whiteboard: [telemetry:fog:m3])

Attachments

(5 files)

FOG needs to upload pings after submission.
The Upload should use the Firefox network stack to do this.
This requires the new upload manager to land.

(the "depends on" bug is closed, but the changes are not in master yet)

Depends on: 1623329
No longer depends on: 1605077

I just had a chat with :baku for other reasons, he suggested looking at fetch and fetchObserver (usable in C++ as well, example) instead of using XHR for new code.

C++ via getting a JS Context, I notice : |

I wonder if there's a friendly and direct networking API in native that we can more easily use without nsI* or JSContext gymnastics in our Rust layer...

Getting a little more detailed with the requirements, this shall:

  1. Send pings when it is pleasant to do so. Scheduling is opportunistic and asynchronous and perhaps on idle. Especially since networking things might have to be main-thread.
  2. Control some headers
    • We do not want anything hitting this endpoint that doesn't need to. This especially means Cookie headers, but extends to anything outside of Content-Type (json), Content-Encoding (gzip, please), Date, User-Agent (useful if something goes wrong), and the basic protocol-level stuff (looking at you, Host)
    • We do want to add some extra things for our own purposes. They all start with X- so I don't expect that to be troubling.
Depends on: 1630758
Assignee: nobody → chutten
Status: NEW → ASSIGNED
Points: --- → 3
Priority: P3 → P1
See Also: → 1628068
Depends on: 1628068
Depends on: 1634375

While waiting for the dependencies to land I explored the problem space a bit and learned some things:

Viaduct

  • The viaduct crate should probably re-export url::Url so that we don't have to match their url version. I filed an Issue
  • It's not strictly clear who should be initializing the backend or how. I went the route of adding some JS (let viaduct = Cc["@mozilla.org/toolkit/viaduct;1"].createInstance(Ci.mozIViaduct); viaduct.Initialize();) right before we call in to init nsITelemetry (which is where we're currently init-ing FOG). I'm using the version of the viaduct impl that is currently up for review in bug 1628068 so I'm way too early to be asking questions like these... but it might still reveal that there's a timing thing we should pay attention to.

Glean SDK

  • Getting the correct version of glean_core was a little tricky because I needed to specify it on both the fog and glean crates (in t/c/g/ and t/c/g/api/ respectively). I wonder if there's anything we can do about that. And in the future when we'll be depending on the glean_sdk crate for the Rust Specific Metrics API, what's to keep us from getting out of sync and accidentally vendoring 2 versions of glean_core?
  • The ping upload changes aren't usable from Rust at the moment because PingRequest isn't exported. See bug 1634745
  • Where exactly should we be calling glean.on_ready_to_submit_pings()? Filed bug 1634754 for the documentation clarification, but in concrete terms I guess we should be calling it... in api::initialize?

Scheduling

  • viaduct asserts if we try to do (sync) networking on the main thread (good!).
  • There's nothing stopping us from using std::thread (which is what I did in my exploration), but as :lina notes it only works for us until we want to dispatch runnables in which case we should use the quite tolerable-looking nsIThread stuff that rkv uses. And I can't help but notice a RefPtr<nsIThread> could sit nicely inside AppState.
    • Dumping to a bg thread like this is enough for now but I wonder if we'll ever in the future need to look into scheduling on idle. For now let's try our best not to schedule anything on a timer and instead allow ourselves to be triggered by activity elsewhere in the process (by say Ping::submit and startup? And IPC? Whatever we choose we must remember to document.)

Anyhoo, that's as far as I can take this for now. Time to de-prioritize and unassign until we see some action in the dependencies.

Assignee: chutten → nobody
Status: ASSIGNED → NEW
Priority: P1 → P3
Depends on: 1637647
Assignee: nobody → chutten
Status: NEW → ASSIGNED

Depends on D76747

Depends on D76748

Depends on D76749

Depends on getting glean_sdk to 30.1.0 so we can have a Vec<u8> out of the ping request.

Depends on: 1640927

Current testing method is the following patch:

diff --git a/toolkit/components/glean/src/lib.rs b/toolkit/components/glean/src/lib.rs
index 4c8119a20dc0..53e30bfa722a 100644
--- a/toolkit/components/glean/src/lib.rs
+++ b/toolkit/components/glean/src/lib.rs
@@ -102,5 +102,12 @@ pub unsafe extern "C" fn fog_init(
         }
     }
 
+    // DO NOT MERGE
+    log::error!("Testing ping sending");
+    let ping = glean::metrics::Ping::new("ping_name", false, true, vec![]);
+    let success = ping.submit(None);
+    log::error!("Ping success? {}", success);
+    // DO NOT MERGE
+
     NS_OK
 }

diff --git a/toolkit/components/glean/src/api.rs b/toolkit/components/glean/src/api.rs
index a700df32a520..8d45ba404442 100644
--- a/toolkit/components/glean/src/api.rs
+++ b/toolkit/components/glean/src/api.rs
@@ -147,6 +147,7 @@ fn register_uploader() {
             const SERVER: &str = "https://incoming.telemetry.mozilla.org";
             let url = Url::parse(SERVER)?.join(&ping_request.path)?;
             let mut req = Request::post(url);
+            req = req.header("X-Debug-ID", "chutten_fog_test")?;
             for (&header_key, header_value) in ping_request.headers.iter() {
                 req = req.header(header_key, header_value)?;
             }

Apply the patch, build and run Firefox, then check the Debug Ping Viewer.

Currently the pings come up empty (didn't add the PingRequest's body to the viaduct Request.), but if they come up at all then it's working.

Blocks: 1632790
Pushed by chutten@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/1845fca9e3ec
Ensure Viaduct is initialized for FOG r=janerik
https://hg.mozilla.org/integration/autoland/rev/932d51ae751e
Add logic for a Ping Scheduler r=janerik
https://hg.mozilla.org/integration/autoland/rev/e7470ab5ae58
Add viaduct (and deps) to fog crate r=janerik
https://hg.mozilla.org/integration/autoland/rev/28e076bc443b
Upload FOG pings using Viaduct. r=janerik

We will eventually have a solution for what FOG does for Gecko when not in
Firefox Desktop, but for now skip the Android question entirely.

Depends on D76750

In the not-too-distant future we'll need to support configurations where we still build FOG into Gecko and not initialize it or its networking underpinnings. But for now we'll just not build anything at all on Android.

Flags: needinfo?(chutten)
Pushed by chutten@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/0b0d93fa2118
Ensure Viaduct is initialized for FOG r=janerik
https://hg.mozilla.org/integration/autoland/rev/eac8f459598f
Add logic for a Ping Scheduler r=janerik
https://hg.mozilla.org/integration/autoland/rev/b878e891386f
Add viaduct (and deps) to fog crate r=janerik
https://hg.mozilla.org/integration/autoland/rev/b68cb2878c3c
Upload FOG pings using Viaduct. r=janerik
https://hg.mozilla.org/integration/autoland/rev/39e6ee02e1dd
For now don't build FOG on Android r=TravisLong
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: