This section describes the primary Temporal workflow concepts and terminology. You should take the time to skim over these terms to give you come context as you dive further in.
Workflow implementations are typically organized into workflows that make decisions determining what's do be done and activities that actually perform the work. For example, workflows may decide to read/write something to a database or call an external service and then then workflow will call an activity to actually perform the operation.
You can think of a workflow as the decider and activities as the primary way for workflows to interact with the outside world, which a workflow should never do directly.
These are workflows that were started in the context of another workflow.
Stubs provide a way define workflows and activities using an interface such that you'll be able to start and interact with workflows and activities using strongly typed methods that will be verified by the .NET compiler when building your code.
This capability was pioneered by Temporal with their Java API and we were strongly encouraged to go this route for .NET (which was an easy decision since it's obviously better). The Go Temporal client does not implement stubs.
These are top-level workflows that were not started as a child workflow.
Temporal tracks workflow and activity executions such that the past decisions and workflow state is durably persisted to the cluster database. This is the secret that allows developers to author workflows as basic code when under the covers, the workflow is essentially a state machine.
Temporal is is a multi tenant service. The unit of isolation is called a namespace. Each namespace acts as a namespace for task list names as well as workflow Ids. For example, when a workflow is started, it is started in a specific namespace. Temporal guarantees a unique workflow Id within a namespace, and supports running workflow executions to use the same workflow Id if they are in different namespaces.
Various configuration options like retention period or archival destination are configured per namespace as well through a special CRUD API or through the Temporal CLI. In the multi-cluster deployment, namespace is a unit of fail-over. Each namespace can only be active on a single Temporal cluster at a time. However, different namespaces can be active in different clusters and can fail-over independently.
Started workflows can be queried synchronously by client applications to retrieve information about the current state of the workflow. This is a read-only operation and a query must never modify workflow state.
Temporal assigns a UUID to each execution of a workflow so they can be uniquely identified. This differs from the workflow ID which is essentially the name of the workflow. For example, you could start a workflow managing a user's junk email folder with a workflow ID like firstname.lastname@example.org-JUNK. Then you could manage, query, or signal the workflow using this stable name. Temporal will assign a UUID as the run ID and if the workflow restarts itself, the new run will retain the same workflow ID, but will be assigned a new run ID.
Signals provides a convienent way to inform a workflow that something external happened. Signals may include arbitrary parameters but signals don't return a result. Signals are delivered asynchronously, meaning the caller may see the signal method return before the workflow actually received the signal.
Workflow signal methods will typically use a WorkflowQueueT to interact with the workflow decision logic.
The workflow and activities you develop will need to be hosted in a workflow service that you'll write. This can be a simple as a Console application that registers the workflows and activities it implements with the Temporal cluster. You'll need to specify the namespace where the workflows and activities will be hosted by Temporal and also a task list string.
Temporal uses the task list you specify to identify all instances of a workflow service running such that work can be distributed to across these services.
Temporal supports external activity completion. This is a less convienent an alternative to signalling. You can take advantage of this by starting an activity that instead of completing the operation itself, obtains a task token from Temporal and then signals Temporal that the activity will be completed externally.
Before the activity returns, it will need to put the token somewhere (like a database) and then you'll have an external service waiting for something to happen that indicates that activity can be completed and then use the task token to complete the activity, specifying the return value if necessary.
This is an application or service that implements one or more workflows and/or activities. When a worker or worker service starts, it will register its workflows and activities with Cadence. Then Temporal will assign workflows and activities to each worker service as it sees fit.
Your workflow and activity code will be executed as required with Temporal recording state as the workflow progresses as well as the results returned by the activities and workflow.
Essentially, a workflow is a method that runs some logic and optionally returns a result. The method is written in C# or some other compatible .NET language. Workflows always interact with the external world via activities. Workflows use activities to query external state so that can impact decisions made by the workflow and workflows also use activities to impact the outside world by writting to a database, sending an email, etc.
Workflows can be configured to run for very long times. Years and perhaps even centuries. Temporal ensures that the state of an executing workflow will be durably persisted such that the workflow can be reassigned to a different worker in response to server failures, load-balancing, etc.
A WorkflowExecution is used to identify an instance of a workflow. This included the workflow and run IDs and may reference a workflow that's still in progress or a completed workflow.
A workflow ID is essentially the name of the workflow. This is an arbitrary string. It's often handy to set this to some kind of business identifier like the name of the entity the workflow is handling.