Client-side Generic Communication Architecture and Protocol [Frontend Observability Working Group]
Now that we have the exit criteria for the WG (what), the next question is "how?"
I'm proposing this solution as a generalized communication system and/or protocol.
Generalized Front End Data Communication
See slack thread (which Slack will eventually purge) for original context, cloned into this section.
@andrewn mentioned a backend system that enables developers to - inline - define Service Level Indicators in their code using a single interface to a larger system.
This proposal is a roughly analogous system, although the concept is more general than SLIs (although nothing is stopping us from adding a sla:...
channel to report various things from the disparate apps).
Here's a video and a diagram:
-
🎞 https://www.youtube.com/watch?v=HwuVkPshK8s -
📊 https://whimsical.com/performance-observability-architecture-JdKKSpCZHpEtzeezsM3vep
One thing to note in addition to the video: this is a largely stateless architecture. The individual apps themselves can dispatch (publish
) messages, and only the systems that care about statefulness (e.g. the performance:...
channel) will store and aggregate state.
There are a few comments (the purple numbers) in the Whimsical chart, and on the final one ("Assigned handler runs"), I describe how the aggregator itself could infer a performance delta based on a sequence of events it has received from an app. So not only is this system generalized and repeatable, it's intended to be stateless at the application interface point, with state abstracted to the places that care (e.g. data aggregators).
Where this fits
Between individual applications (e.g. the "Diffs" app, in my Code Review case) and our reporting infrastructure.
Other things
Because my proposal is "high-level" "back-of-the-front", we may also consider these other things as supplementary exit criteria:
- App-friendly "cookbook" style recipes for performance or error reporting, e.g.
import { provider } from '@gitlab/message-channels.js'; import { APP_INIT, APP_DONE } from './constants.js'; // later in your component business logic created() { this.perfCommsChannel = provider.getChannel('performance:[your group]:[your app]'); this.perfCommsChannel.publish( APP_INIT ); }, async mounted() { await this.$nextTick(); this.perfCommsChannel.publish( APP_DONE ); }
- (This generalized communication system, included for cohesive "flow")
- Generic handler functions, e.g. if we get a message in the channel
performance:CodeReview:Diffs
, and there's no custom handler, how should we segment and normalize that inbound message? - Adapters for our services (Sentry, Snowplow, etc.) to take
👆🏻 normalized data and send it to our reporting tools - Clean up and upgrade tools, centralize implementations (e.g. no more random Snowplow code scattered throughout - just send the message to the
telemetry:...
channel)