Qian Chen d83b12e87e Emit namespace CRUD lifecycle wide events (register / update / failover / delete) (#11563)
## What changed?

Adds structured `namespace_lifecycle` wide events for namespace
mutations.

### Namespace mutations

- `namespace_registered` is emitted after successful registration.
- `namespace_updated` is emitted after successful namespace updates and
includes full `before` / `after` snapshots, requested values, and
`requested_fields` identifying what the caller explicitly set.
- Local-to-global promotion is distinguished by `is_promotion` and
`promote_namespace_requested`.
- Active-cluster failover is distinguished by `is_failover` and the
active-cluster transition in `before` / `after`.
- Deprecation is represented by the `Registered` to `Deprecated` state
transition.
- Workflow-rule creation and deletion include the affected rule ID and
detail, plus force-scan and request-ID data when supplied.
- `namespace_renamed` is emitted by the delete-namespace worker when the
namespace is renamed to its tombstone name. This is the observable
deletion point because namespace deletion is local and is not replicated
as a namespace operation.

The snapshots cover namespace info, configuration, archival settings,
replication topology/state, failover versions/history, custom
search-attribute aliases, bad binaries, and workflow-rule IDs. Request
security tokens are not captured.

### Dynamic configuration

All namespace lifecycle emission is gated by the new global
dynamic-config setting:

```yaml
system.emitNamespaceLifecycleEvents:
  - value: true
```

The setting defaults to `false` and is evaluated dynamically by
frontend, history, and worker producers. In addition to the new
namespace mutation events, the gate covers the existing handover-related
namespace lifecycle events:

- `shard_handover_watermark_set`
- `shard_handover_watermark_removed`
- `shard_handover_incomplete`

This PR does not introduce or change those handover event payloads; it
only makes their emission follow the same namespace lifecycle flag.

## Why?

Existing RPC metrics and logs do not provide a structured, field-level
record of namespace control-plane changes. These events provide an
attributable and queryable view of what changed, including promotion
versus failover, requested versus persisted values, rule mutations, and
delete-pipeline renames. The shared gate lets operators enable the
complete namespace lifecycle signal consistently across services.

## How did you test?

- [x] Unit tests with `-tags test_dep` for frontend emission and
disabled gating, history handover gating, delete-namespace rename
emission, migration incomplete-handover gating, dynamic config, and
common wide-event payloads.
- [x] `make lint-code` (`0 issues`).
- [x] Full local two-cluster E2E using
`config/development-cluster-a.yaml` and
`config/development-cluster-b.yaml` with a JSON event logger.
- With the flag enabled, validated register, ordinary update,
workflow-rule create/delete, deprecate, delete rename, promotion,
cluster-list update, and failover from cluster A to B.
- Also verified that the existing handover producers remain functional
when enabled: all 16 shard watermark additions and removals on cluster B
and a forced 32-shard incomplete-handover event on cluster A.
- With the flag disabled, repeated all producer paths and confirmed zero
emitted bytes. The failure-only incomplete-handover path was rerun after
disabling the flag and left both event-log counts unchanged.
- Confirmed live dynamic-config enable/disable behavior without
restarting either cluster.

### Abridged failover event

```json
{
  "event_name": "namespace_lifecycle",
  "phase": "namespace_updated",
  "details": {
    "before": {
      "active_cluster": "cluster-a",
      "failover_version": 1
    },
    "after": {
      "active_cluster": "cluster-b",
      "failover_version": 2
    },
    "requested": {
      "active_cluster": "cluster-b"
    },
    "requested_fields": ["active_cluster"],
    "is_failover": true,
    "is_promotion": false
  }
}
```

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-18 18:17:32 -07:00
2025-04-07 18:42:37 -07:00

Temporal—durable execution platform

GitHub Release GitHub License Code Coverage Community Go Report Card

Introduction   •   Getting Started   •   Contributing   •   Temporal Docs   •   Temporal 101

Introduction

Temporal is a durable execution platform that enables developers to build scalable applications without sacrificing productivity or reliability. The Temporal server executes units of application logic called Workflows in a resilient manner that automatically handles intermittent failures, and retries failed operations.

Temporal is a mature technology that originated as a fork of Uber's Cadence. It is developed by Temporal Technologies, a startup by the creators of Cadence.

image

Getting Started

Download and Start Temporal Server Locally

Execute the following commands to start a pre-built image along with all the dependencies.

brew install temporal
temporal server start-dev

Refer to Temporal CLI documentation for more installation options.

Run the Samples

Clone or download samples for Go or Java and run them with the local Temporal server. We have a number of HelloWorld type scenarios available, as well as more advanced ones. Note that the sets of samples are currently different between Go and Java.

Use CLI

Use Temporal CLI to interact with the running Temporal server.

temporal operator namespace list
temporal workflow list

Use Temporal Web UI

Try Temporal Web UI by opening http://localhost:8233 for viewing your sample workflows executing on Temporal.

Repository

This repository contains the source code of the Temporal server. To implement Workflows, Activities and Workers, use one of the supported languages.

Contributing

We'd love your help in making Temporal great.

Helpful links to get started:

License

MIT License

Languages
Go 99.5%
Shell 0.2%
PLpgSQL 0.2%
Makefile 0.1%