Skip to content

Improve re-usability of ringpop membership & PerNamespaceWorker#9321

Merged
02strich merged 2 commits intomainfrom
stefan/ext-service
Feb 21, 2026
Merged

Improve re-usability of ringpop membership & PerNamespaceWorker#9321
02strich merged 2 commits intomainfrom
stefan/ext-service

Conversation

@02strich
Copy link
Copy Markdown
Contributor

@02strich 02strich commented Feb 13, 2026

What changed?

This makes the ServiceName to ServiceType mapping in the Ringpop membership implementation more extensible, and exports the worker-service's PerNamespaceWorker.

Why?

As the code base grows, it becomes useful to enable building system services in seperate repositories (just to manage growth).

This approach unblocks re-use of membership and PerNamespaceWorker capabilities that are more generically useful than solely inside the server.

How did you test it?

  • built
  • run locally and tested manually
  • covered by existing tests
  • added new unit test(s)
  • added new functional test(s)

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Feb 13, 2026

CLA assistant check
All committers have signed the CLA.

@02strich 02strich changed the title Add support for services outside of this code base Improve re-usability of ringpop membership & PerNamespaceWorker Feb 17, 2026
@02strich 02strich force-pushed the stefan/ext-service branch 2 times, most recently from d708085 to c6be5b5 Compare February 17, 2026 23:48
}

func (wm *perNamespaceWorkerManager) Start(
func (wm *PerNamespaceWorkerManager) Start(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

you should change the key in the AddListener call to something unique in case these end up in the same process. I like to use fmt.Sprintf("%p", wm)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ah gotcha, made the change

@02strich 02strich closed this Feb 18, 2026
@02strich 02strich reopened this Feb 18, 2026
This updates the mapping from service name to ringpop role to using a map instead of an if-else chain. The map enables distributed configurability instead of depending on defining all scenarios in this single place.
@02strich 02strich force-pushed the stefan/ext-service branch 2 times, most recently from f2ce416 to 5759690 Compare February 18, 2026 18:50
@02strich 02strich marked this pull request as ready for review February 18, 2026 19:16
@02strich 02strich requested review from a team as code owners February 18, 2026 19:16
@02strich 02strich requested review from bergundy and dnr February 20, 2026 17:03
Copy link
Copy Markdown
Member

@bergundy bergundy left a comment

Choose a reason for hiding this comment

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

Approved with a suggestion.

Comment on lines +457 to +472
var (
serviceNameToServiceTypeEnumMap = map[primitives.ServiceName]persistence.ServiceType{}
)

func RegisterServiceNameToServiceTypeEnum(serviceName primitives.ServiceName, serviceType persistence.ServiceType) {
serviceNameToServiceTypeEnumMap[serviceName] = serviceType
}

func init() {
RegisterServiceNameToServiceTypeEnum(primitives.AllServices, persistence.All)
RegisterServiceNameToServiceTypeEnum(primitives.FrontendService, persistence.Frontend)
RegisterServiceNameToServiceTypeEnum(primitives.InternalFrontendService, persistence.InternalFrontend)
RegisterServiceNameToServiceTypeEnum(primitives.HistoryService, persistence.History)
RegisterServiceNameToServiceTypeEnum(primitives.MatchingService, persistence.Matching)
RegisterServiceNameToServiceTypeEnum(primitives.WorkerService, persistence.Worker)
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
var (
serviceNameToServiceTypeEnumMap = map[primitives.ServiceName]persistence.ServiceType{}
)
func RegisterServiceNameToServiceTypeEnum(serviceName primitives.ServiceName, serviceType persistence.ServiceType) {
serviceNameToServiceTypeEnumMap[serviceName] = serviceType
}
func init() {
RegisterServiceNameToServiceTypeEnum(primitives.AllServices, persistence.All)
RegisterServiceNameToServiceTypeEnum(primitives.FrontendService, persistence.Frontend)
RegisterServiceNameToServiceTypeEnum(primitives.InternalFrontendService, persistence.InternalFrontend)
RegisterServiceNameToServiceTypeEnum(primitives.HistoryService, persistence.History)
RegisterServiceNameToServiceTypeEnum(primitives.MatchingService, persistence.Matching)
RegisterServiceNameToServiceTypeEnum(primitives.WorkerService, persistence.Worker)
}
var serviceNameToServiceTypeEnumMap = map[primitives.ServiceName]persistence.ServiceType{
primitives.AllServices: persistence.All,
primitives.FrontendService: persistence.Frontend,
primitives.InternalFrontendService: persistence.InternalFrontend,
primitives.HistoryService: persistence.History,
primitives.MatchingService: persistence.Matching,
primitives.WorkerService: persistence.Worker,
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

there still needs to be a RegisterServiceNameToServiceTypeEnum, that's the whole point of this change

RegisterServiceNameToServiceTypeEnum(primitives.WorkerService, persistence.Worker)
}

func serviceNameToServiceTypeEnum(name primitives.ServiceName) (persistence.ServiceType, error) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Seems like a redundant helper but 🤷

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

wanted to keep the changes contained - can remove it down the line

Copy link
Copy Markdown
Contributor

@dnr dnr left a comment

Choose a reason for hiding this comment

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

couple nitpicks but no blockers, so approving now

Comment on lines +457 to +472
var (
serviceNameToServiceTypeEnumMap = map[primitives.ServiceName]persistence.ServiceType{}
)

func RegisterServiceNameToServiceTypeEnum(serviceName primitives.ServiceName, serviceType persistence.ServiceType) {
serviceNameToServiceTypeEnumMap[serviceName] = serviceType
}

func init() {
RegisterServiceNameToServiceTypeEnum(primitives.AllServices, persistence.All)
RegisterServiceNameToServiceTypeEnum(primitives.FrontendService, persistence.Frontend)
RegisterServiceNameToServiceTypeEnum(primitives.InternalFrontendService, persistence.InternalFrontend)
RegisterServiceNameToServiceTypeEnum(primitives.HistoryService, persistence.History)
RegisterServiceNameToServiceTypeEnum(primitives.MatchingService, persistence.Matching)
RegisterServiceNameToServiceTypeEnum(primitives.WorkerService, persistence.Worker)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

there still needs to be a RegisterServiceNameToServiceTypeEnum, that's the whole point of this change


func PerNamespaceWorkerManagerProvider(params perNamespaceWorkerManagerInitParams) *PerNamespaceWorkerManager {
return NewPerNamespaceWorkerManager(
params.Logger,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

could just pass params as a whole, so there's fewer places to change when adding dependencies? I guess this separates the fx stuff more cleanly, so either way

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yeah the goal was separating the FX a tiny bit more so it is not hard assumed which fields come FX and which come from somewhere else

Making the PerNamespaceWorker helper from the worker service exported so it can be re-used by other components.
@02strich 02strich merged commit aff1163 into main Feb 21, 2026
46 checks passed
@02strich 02strich deleted the stefan/ext-service branch February 21, 2026 00:41
02strich added a commit that referenced this pull request Feb 23, 2026
* origin/main:
  CHASM: improve support for implementing Terminate method (#9351)
  Add testhooks package documentation (#9373)
  Improve re-usability of ringpop membership & PerNamespaceWorker (#9321)
  Fairness counter: fix heap bug in map counter (#9370)
  Avoid finalGC when ack level is zero (#9371)
  Fairness counter: persist top K keys (#9188)
  Flake Fix: In Reactivation Cache tests, wait for appropriate delays when confirming expected drainage status (#9352)
  Include transient and speculative WFT events in GetWorkflowExecutionHistoryResponse (#9325)
  Fix flaky test TestTransitionDuringTransientTask (#9356)
  Add per-workflow scheduler for history task processing (#9141)
  Populate currentAttemptScheduledTime on PollActivityTaskQueueResponse for standalone activities (#9333)
  Standalone activity heartbeating bug fix (#9354)
  Revert "Last part of making Nexus work OOTB" (#9343)
  Convert flake report from Python to Go (#9334)
  Do not enforce payload limits for system nexus endpoint (#9344)
stephanos pushed a commit to stephanos/temporal that referenced this pull request Feb 23, 2026
…oralio#9321)

## What changed?
This makes the ServiceName to ServiceType mapping in the Ringpop
membership implementation more extensible, and exports the
worker-service's PerNamespaceWorker.

## Why?
As the code base grows, it becomes useful to enable building system
services in seperate repositories (just to manage growth).

This approach unblocks re-use of membership and PerNamespaceWorker
capabilities that are more generically useful than solely inside the
server.

## How did you test it?
- [X] built
- [X] run locally and tested manually
- [X] covered by existing tests
- [ ] added new unit test(s)
- [ ] added new functional test(s)
iw added a commit to iw/temporal that referenced this pull request Mar 19, 2026
Merges temporalio/temporal main branch up to df2e384.

Key upstream changes:
- Customizable serialization (temporalio#8426): EncodingTypeFromEnv(), EncodingType() on Encoder
- Per-workflow scheduler for history task processing (temporalio#9141)
- Ringpop membership & PerNamespaceWorker reusability (temporalio#9321)
- Transient/speculative WFT events in history response (temporalio#9325)
- Per-check diagnostics in DeepHealthCheck API (temporalio#9350)
- Fairness counter heap bug fix (temporalio#9370)
- System nexus endpoint (temporalio#9002)
- Mixed brain non-blocking (temporalio#9406)
- interface{} → any across persistence layer
- Various CI, test, and chasm improvements

DSQL fork code preserved:
- TxRetryPolicy/TxRetryMetrics/TxRetryPolicyProvider (common.go)
- ExecutionStoreCreator interface and factory wrapping (factory.go)
- OCC-aware lockShard bypass (shard.go)
- PoolSizeHint ephemeral pool sizing (version_checker.go)
- DSQL-safe InitializeSystemNamespaces (metadata_manager.go)
- Snowflake ID generator (idgenerator.go)
- RegisterPluginAlias (store.go)
- Full DSQL plugin (sqlplugin/dsql/)
birme pushed a commit to eyevinn-osaas/temporal that referenced this pull request Mar 23, 2026
…oralio#9321)

## What changed?
This makes the ServiceName to ServiceType mapping in the Ringpop
membership implementation more extensible, and exports the
worker-service's PerNamespaceWorker.

## Why?
As the code base grows, it becomes useful to enable building system
services in seperate repositories (just to manage growth).

This approach unblocks re-use of membership and PerNamespaceWorker
capabilities that are more generically useful than solely inside the
server.

## How did you test it?
- [X] built
- [X] run locally and tested manually
- [X] covered by existing tests
- [ ] added new unit test(s)
- [ ] added new functional test(s)
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.

4 participants