Skip to content

Conversation

@prathyushpv
Copy link
Contributor

@prathyushpv prathyushpv commented Dec 16, 2025

What changed?

This PR extends the raw history optimization to pass raw history bytes from History Service → Matching Service → Frontend without deserialization in Matching Service.

Key changes:

  1. History Service:
    • When SendRawHistoryBetweenInternalServices is enabled, sets RawHistoryBytes (field 21) with raw proto-encoded history batches
  2. Matching Service:
    • Passes raw history bytes through to frontend via PollWorkflowTaskQueueResponseWithRawHistory
    • Uses wire-compatible proto messages so gRPC auto-deserializes [][]byteHistory on the client side
  3. Frontend:
    • Receives raw history in RawHistory field (auto-deserialized by gRPC)
    • Processes search attributes for raw history since it bypasses history service's normal processing
  4. Proto definitions:
    • Added raw_history_bytes (field 21) to RecordWorkflowTaskStartedResponse
    • Added PollWorkflowTaskQueueResponseWithRawHistory message with wire-compatible layout
    • Added raw_history (field 22) to PollWorkflowTaskQueueResponse

Why?

When history.sendRawHistoryBetweenInternalServices is enabled, the previous implementation only avoided deserialization from persistence → History Service. However, Matching Service was still deserializing history events (via gRPC auto-deserialization) and re-serializing them when forwarding to Frontend.

This change eliminates that unnecessary serialization/deserialization cycle in Matching Service by:

  1. Having History Service send raw bytes directly
  2. Having Matching Service forward these raw bytes without parsing
  3. Having Frontend receive the bytes which gRPC auto-deserializes

This reduces CPU usage in Matching Service for workflows with large histories.

How did you test it?

  • built
  • covered by existing tests
  • added new unit test(s)
  • added new functional test(s) (tests/workflow_task_test.go)

Potential risks

SendRawHistoryBetweenInternalServices must be disabled when rolling back from this version to an older version.

@prathyushpv prathyushpv requested review from a team as code owners December 16, 2025 00:05
@prathyushpv prathyushpv marked this pull request as draft December 16, 2025 00:06
prathyushpv and others added 9 commits December 15, 2025 16:30
Resolved conflicts:
- service/history/api/recordworkflowtaskstarted/api.go: kept our return type, added main's GetActiveNamespace parameter
- api/matchingservice/v1/request_response.pb.go: regenerated proto files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add //nolint:staticcheck comments to suppress SA1019 deprecation warnings
for RawHistory field usage. These deprecated fields are intentionally used
for backward compatibility during rolling upgrades.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Keep SendRawHistoryBetweenInternalServices default as false
- TestQueryNoCurrentPollersButRecentPollers, TestQueryNoRecentPoller: Use emptyClientPollWorkflowTaskQueueResponse for mock client tests since client interface uses PollWorkflowTaskQueueResponse (not the WithRawHistory variant)
@prathyushpv prathyushpv marked this pull request as ready for review December 30, 2025 17:54
@prathyushpv prathyushpv changed the title WIP: Send raw history events from matching to frntend Send raw history events from matching to frontend service Dec 30, 2025
@prathyushpv prathyushpv requested review from dnr and yycptt January 9, 2026 17:53
Copy link
Member

@yycptt yycptt left a comment

Choose a reason for hiding this comment

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

synced offline. I think we need a separate flag for this change or we will have a regression on the history service side (an extra decoding)

// History client will deserialize this message to RecordWorkflowTaskStartedResponse.
// Deprecated: This field is being replaced by raw_history_bytes which sends raw bytes
// instead of a proto-decoded History. This avoids matching service having to decode history.
temporal.api.history.v1.History raw_history = 20 [deprecated = true];
Copy link
Member

Choose a reason for hiding this comment

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

plz add comment for the plan of deprecating related fields/messages.

repeated bytes raw_history_bytes = 21;
}

// RecordWorkflowTaskStartedResponseWithRawHistory is wire-compatible with RecordWorkflowTaskStartedResponse.
Copy link
Member

Choose a reason for hiding this comment

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

looks like this is no longer used and can be removed?

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