-
Notifications
You must be signed in to change notification settings - Fork 56
Description
Context
PR #829 introduced a cleaner event stream pattern for ArkService.GetEventStream:
- Client opens one stream connection
- Server immediately emits
StreamStartedEventwith a stream ID - Client uses
UpdateStreamTopics(unary RPC) to dynamically add/remove/overwrite topics on that stream - Result: one connection to manage instead of juggling subscribe-then-stream choreography
The IndexerService in indexer.proto currently uses an older multi-step pattern:
- Client calls
SubscribeForScripts(unary) → gets back asubscription_id - Client opens
GetSubscription(subscription_id)(server stream) → receives events - To modify scripts mid-stream, client calls
SubscribeForScriptsagain with the samesubscription_idto add, orUnsubscribeForScriptsto remove
This requires the client to manage the lifecycle of subscription creation before it can open the stream, and uses two separate unary RPCs for what is conceptually add/remove.
Proposal
Align IndexerService with the ArkService pattern from #829 — no breaking changes to existing RPCs.
1. Make subscription_id optional in GetSubscriptionRequest
message GetSubscriptionRequest {
// If empty, server creates a new subscription automatically.
// Existing clients can still pass a pre-created subscription_id.
string subscription_id = 1;
// Optional: scripts to subscribe to on stream creation.
// Ignored if subscription_id already has scripts.
repeated string scripts = 2;
}When subscription_id is empty, the server creates a subscription internally, just like GetEventStream creates a listener. This lets new clients skip the SubscribeForScripts bootstrapping call entirely.
The optional scripts field lets the client subscribe to an initial set of scripts in the same call — single step to go from nothing to a fully active, filtered stream.
2. Add SubscriptionStartedEvent to the stream response
message GetSubscriptionResponse {
oneof data {
IndexerHeartbeat heartbeat = 1;
IndexerSubscriptionEvent event = 2;
SubscriptionStartedEvent subscription_started = 3; // NEW
}
}
message SubscriptionStartedEvent {
string subscription_id = 1;
}Emitted immediately upon stream creation (mirrors StreamStartedEvent). The client now has the subscription ID without needing to call SubscribeForScripts first.
3. (Optional) Add UpdateSubscriptionScripts unary RPC
// Mirrors UpdateStreamTopics from ArkService
rpc UpdateSubscriptionScripts(UpdateSubscriptionScriptsRequest) returns (UpdateSubscriptionScriptsResponse) {
option (meshapi.gateway.http) = {
post: "/v1/indexer/script/updateScripts"
body: "*"
};
};
message UpdateSubscriptionScriptsRequest {
string subscription_id = 1;
oneof scripts_change {
ModifyScripts modify = 2;
OverwriteScripts overwrite = 3;
}
}
message ModifyScripts {
repeated string add_scripts = 1;
repeated string remove_scripts = 2;
}
message OverwriteScripts {
repeated string scripts = 1;
}
message UpdateSubscriptionScriptsResponse {
repeated string scripts_added = 1;
repeated string scripts_removed = 2;
repeated string all_scripts = 3;
}This consolidates add/remove into a single RPC with oneof semantics, matching the UpdateStreamTopics pattern. The existing SubscribeForScripts and UnsubscribeForScripts RPCs continue to work unchanged.
Backward compatibility
| Client | What changes? |
|---|---|
| Old clients | Nothing. SubscribeForScripts → GetSubscription(id) → UnsubscribeForScripts all remain and work identically. |
| New clients | GetSubscription() (no ID, optional initial scripts) → receive SubscriptionStartedEvent → UpdateSubscriptionScripts to modify. Single connection, cleaner lifecycle. |
Migration path
Once new clients have adopted the consolidated pattern, the old SubscribeForScripts / UnsubscribeForScripts RPCs can be deprecated (but not removed) in a future version.
Related
- rpc for updating event stream topics #829 / Update topics without restarting stream #728 —
ArkServiceevent stream consolidation