Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Set the scope_manager RFC to Test. #122

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions rfc/scope_manager.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Scope Manager

**Current State:** Draft
**Current State:** Test
Copy link

Choose a reason for hiding this comment

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

Hello @carlosalberto,
I think you should not remove two ending spaces here.
They are required to split lines.

When you do want to insert a <br /> break tag using Markdown, you end a line with two or more spaces, then type return.

Currently, you have Current State and Author on the same line.

Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't a blank line between them do the same? Linters do not like trailing spaces (they even show up as red in git diff).

Alternatively, in this case it's appropriate to us bullet points for the metadata.

Copy link

Choose a reason for hiding this comment

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

Wouldn't a blank line between them do the same?

No, it wouldn't. The result won't be the same.

Copy link

Choose a reason for hiding this comment

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

Linters do not like trailing spaces

I know, but it's an issue of those linters and git.
It's not a Markdown issue.

**Author:** [carlosalberto](https://github.com/carlosalberto)

In the OpenTracing specification, under the "Optional API Elements" section, it is mentioned languages may choose to provide utilities to pass an active **Span** around a single process.
Expand All @@ -23,15 +23,17 @@ New `ScopeManager` and `Scope` interfaces are added to the specification, and th

The `ScopeManager` interface allows setting the active `Span` in a call-context storage section, and has the following members:

* **activate**, capability to set the specified `Span` as the active one for the current call-context, returning a `Scope` containing it. A required boolean parameter **finish span on close** will mark whether the returned `Scope` should, upon deactivation, **finish** the contained `Span`.
* **active**, the `Scope` containing the current active `Span` if any, or else null/nothing.
* **activate**, capability to set the specified `Span` as the active one for the current call-context, returning a `Scope` to later end its active period.
An **optional** feature to optionally **finish** the `Span` upon `Scope` deactivation may be provided, depending on its suitability for the language. It would require a boolean parameter **finish span on close**.
* **active Span**, the `Span` that is currently active, if any, or else null/nothing.
* **active**, the corresponding `Scope` for the current active `Span` if any, or else null/nothing.

## Scope

The `Scope` interface acts as a container of the active `Span` for the current-call context, and has the following members:

* **span**, the contained active `Span` for this call-context. It will never be null/nothing.
* **close**, marking the end of the active period for the current `Span`, and optionally **finishing** it. Calling it more than once leads to undefined behavior.
* **span** (optional), the related active `Span` for this call-context, depending on its suitability for the language. It will never be null/nothing.

If the language supports some kind of auto finishing statement (such as `try` for Java, or `with` for Python), `Scope` should adhere to such convention. Additionally, `Scope` is not guaranteed to be thread-safe.

Expand All @@ -40,7 +42,8 @@ If the language supports some kind of auto finishing statement (such as `try` fo
The `Tracer` interface will be extended with:

* **scope manager**, the `ScopeManager` tracking the active `Span` for this instance.
* **start active span**, a new behavior for starting a new `Span`, which will be automatically marked as active for the current call-context. It will return a `Scope`. A parameter **finish span on close** will mark whether the `Scope` should, upon deactivation, **finish** the contained `Span`. A default value for this parameter may be provided, depending on the suitability for the language and its use cases.
* **start active span** (optional), a new behavior for starting a new `Span`, which will be automatically marked as active for the current call-context. It will return a `Scope`.
An **optional** feature to optionally finish `Span` upon `Scope` deactivation may be provided, depending on its suitability for the language. It would require a boolean parameter **finish span on close**. A default value for this parameter may be provided, depending again on the suitability for the language and its use cases.
* Both **start span** and **start active span** will implicitly use any active `Span` as the parent for newly created `Span`s (with a `ChildOf` relationship), unless the parent is explicitly specified, or (the new) **ignore active span** parameter is specified (in which case the resulting `Span` will have no parent at all).

# Use Cases
Expand Down
86 changes: 83 additions & 3 deletions specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,16 +117,30 @@ These can all be valid timing diagrams for children that "FollowFrom" a parent.

## The OpenTracing API

There are three critical and inter-related types in the OpenTracing specification: `Tracer`, `Span`, and `SpanContext`. Below, we go through the behaviors of each type; roughly speaking, each behavior becomes a "method" in a typical programming language, though it may actually be a set of related sibling methods due to type overloading and so on.
There are three critical and inter-related types in the OpenTracing specification: `Tracer`, `Span`, and `SpanContext`, as well as two optional helper types: `ScopeManager` and `Scope`. Below, we go through the behaviors of each type; roughly speaking, each behavior becomes a "method" in a typical programming language, though it may actually be a set of related sibling methods due to type overloading and so on.

When we discuss "optional" parameters, it is understood that different languages have different ways to construe such concepts. For example, in Go we might use the "functional Options" idiom, whereas in Java we might use a builder pattern.

### Within-process `Span` propagation

For any thread or execution unit, at most one `Span` may be active, and it is important that such `Span` is available at any point down the execution chain, in order to define proper **Reference** relationships among `Span`s.

For platforms where the call-context is explicitly propagated down the execution chain -such as `Go`-, such context can be used to store the active `Span` at all times.

For platforms not propagating a call-context, it is inconvenient to pass the active `Span` from function to function manually. For those platforms, the `Tracer` interface must contain a `ScopeManager` instance that stores and handles the active `Span` with the help of the `Scope` interface to end its active period.

### `Tracer`

The `Tracer` interface creates `Span`s and understands how to `Inject`
(serialize) and `Extract` (deserialize) them across process boundaries.
The `Tracer` interface creates `Span`s, understands how to `Inject`
(serialize) and `Extract` (deserialize) them across process boundaries, and optionally contains a `ScopeManager` instance to handle the active `Span`.
Formally, it has the following capabilities:

#### Retrieve the `ScopeManager` (Optional)

There should be no parameters.

**Returns** the used `ScopeManager` instance to set and retrieve the active `Span` and its corresponding `Scope`. The mentioned active instance is additionally used by default as the implicit parent for newly created `Span`s, in case no **references** were provided.

#### Start a new `Span`

Required parameters
Expand All @@ -144,11 +158,26 @@ For example, here are potential **operation names** for a `Span` that gets hypot
Optional parameters

- Zero or more **references** to related `SpanContext`s, including a shorthand for `ChildOf` and `FollowsFrom` reference types if possible.
- An optional explicit **ignore active Span** boolean specifying whether the active `Span` should be ignored and not used as the implicit parent, in case no **references** were provided.
- An optional explicit **start timestamp**; if omitted, the current walltime is used by default
- Zero or more **tags**

**Returns** a `Span` instance that's already started (but not `Finish`ed)

#### Start a `Scope` with a new `Span` (Optional)

This operation does the same as **Start a new `Span`**, in addition to setting the newly created `Span` as the active instance for the current thread or execution unit through the contained `ScopeManager` instance.

It is **highly** encouraged that language implementations (methods or fields) of this operation include a `Scope` suffix, in order to make clear the type of the returned instance.

Parameters are the same as **Start a new Span**, with the addition of:

- A **finish Span on close** boolean specifying whether the contained `Span` should be closed upon `Scope` being `Close`d. This is a special parameter that can be either required or optional (along with a default value), depending on the specific needs of the platform.

**Returns** a `Scope` instance corresponding to the `Span` that was started (but not `Finish`ed).

Note: This operation is defined as optional, and its existence will depend on its suitability for the thread model, language semantics, API guidelines and other considerations for every given language.

#### Inject a `SpanContext` into a carrier

Required parameters
Expand Down Expand Up @@ -250,6 +279,57 @@ In OpenTracing we force `SpanContext` instances to be **immutable** in order to

This is modeled in different ways depending on the language, but semantically the caller should be able to efficiently iterate through all baggage items in one pass given a `SpanContext` instance.

### `ScopeManager`

The `ScopeManager` interface sets and retrieves the active `Span` and its corresponding `Scope`.
Formally, it has the following capabilities:

#### Activate a `Span`

Prior to setting a provided `Span` as active for the current thread or execution unit, the previously active instance needs to be stashed away, so it can be restored afterwards.

Required parameters

- **span**, the `Span` instance to be set as active.
- **finish Span on close** (optional feature), a boolean value specifying whether the `Span` should be `Finish`ed upon being deactivated through its container `Scope` being `Close`d.
Note: This feature is defined as optional, and its existence will depend on its suitability for the thread model, language semantics, API guidelines and other considerations for every given language.

**Returns** a `Scope` instance corresponding to the newly activated `Span`.

#### Retrieve the active `Span`

There should be no parameters.

**Returns** the active `Span` instance, or else `null` if there's none for the current thread or execution unit.

#### Retrieve the active `Scope`

There should be no parameters.

**Returns** a `Scope` instance corresponding to the active `Span`, or else `null` if there's no active `Span` for the current thread or execution unit.

### `Scope`

The `Scope` interface is used to end the active period for a given `Span`,and it is not guaranteed to be thread-safe. It has the following capabilities:

#### Retrieve the `Span` (optional)

There should be no parameters.

**Returns** its corresponding `Span`. The returned value can never be `null`.

Note: This operation is defined as optional, and its existence will depend on its suitability for the thread model, language semantics, API guidelines and other considerations for every given language.

#### Close the `Scope`

Closing the `Scope` will make its corresponding `Span` stop being the currently active instance for the thread or execution unit.

If the `Scope` instance being `Close`d does not correspond to the actually active one, **no action** will be performed. An additional side effect will be restoring the previously active `Span` instance along with its corresponding `Scope` instance.

There should be no parameters.

**`Finish`ing the `Span`** is defined as an optional feature. Depending on a **finish Span on close** parameter that might have been provided during activation, its corresponding `Span` will be `Finish`ed. Note: This feature is defined as optional, and its existence will depend on its suitability for the thread model, language semantics, API guidelines and other considerations for every given language.

### `NoopTracer`

All OpenTracing language APIs must also provide some sort of `NoopTracer` implementation which can be used to flag-control OpenTracing or inject something harmless for tests (et cetera). In some cases (for example, Java) the `NoopTracer` may be in its own packaging artifact.
Expand Down