Skip to content

Commit

Permalink
Improve open-telemetry/context documentation (#830)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nevay authored Sep 23, 2022
1 parent c0a6279 commit 215731f
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 13 deletions.
1 change: 1 addition & 0 deletions .phan/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
'PhanAccessClassInternal',
'PhanAccessMethodInternal',
'PhanAccessPropertyInternal',
'PhanTemplateTypeNotUsedInFunctionReturn',
],

// A regular expression to match files to be excluded
Expand Down
66 changes: 55 additions & 11 deletions src/Context/ContextInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,83 @@

namespace OpenTelemetry\Context;

/**
* Immutable execution scoped propagation mechanism.
*
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/README.md#context
*/
interface ContextInterface
{
/**
* @param non-empty-string $key
* Creates a new context key.
*
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/context/context.md#create-a-key
* @param non-empty-string $key name of the key
* @return ContextKeyInterface created key
*
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/README.md#create-a-key
*/
public static function createKey(string $key): ContextKeyInterface;

/**
* Returns the current context.
*
* @return ContextInterface current context
*
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/README.md#get-current-context
*/
public static function getCurrent(): ContextInterface;

/**
* Makes `$this` the currently active {@see ContextInterface}.
* Attaches this context as active context.
*
* The returned scope has to be {@link ScopeInterface::detach()}ed. In most
* cases this should be done using a `try-finally` statement:
* ```php
* $scope = $context->activate();
* try {
* // ...
* } finally {
* $scope->detach();
* }
* ```
*
* @return ScopeInterface scope to detach the context and restore the previous
* context
*
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/README.md#attach-context
*/
public function activate(): ScopeInterface;

/**
* This adds a key/value pair to this Context.
* Returns a context with the given key set to the given value.
*
* @template T
* @param ContextKeyInterface<T> $key key to set
* @param T|null $value value to set
* @return ContextInterface a context with the given key set to `$value`
*
* @psalm-template T
* @psalm-param ContextKeyInterface<T> $key
* @psalm-param T|null $value
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/README.md#set-value
*/
public function with(ContextKeyInterface $key, $value): ContextInterface;

/**
* Returns a context with the given value set.
*
* @param ImplicitContextKeyedInterface $value value to set
* @return ContextInterface a context with the given `$value`
*
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/README.md#set-value
*/
public function withContextValue(ImplicitContextKeyedInterface $value): ContextInterface;

/**
* Fetch a value from the Context given a key value.
* Returns the value assigned to the given key.
*
* @template T
* @param ContextKeyInterface<T> $key key to get
* @return T|null value assigned to `$key`, or null if no such value exists
*
* @psalm-template T
* @psalm-param ContextKeyInterface<T> $key
* @psalm-return T|null
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/README.md#get-value
*/
public function get(ContextKeyInterface $key);
}
18 changes: 18 additions & 0 deletions src/Context/ContextStorageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,27 @@

interface ContextStorageInterface
{
/**
* Returns the current scope.
*
* @return ContextStorageScopeInterface|null current scope, or null if no
* scope was attached in the current execution unit
*/
public function scope(): ?ContextStorageScopeInterface;

/**
* Returns the current context.
*
* @return ContextInterface current context
*/
public function current(): ContextInterface;

/**
* Attaches the context as active context.
*
* @param ContextInterface $context context to attach
* @return ContextStorageScopeInterface scope to detach the context and
* restore the previous context
*/
public function attach(ContextInterface $context): ContextStorageScopeInterface;
}
5 changes: 5 additions & 0 deletions src/Context/ContextStorageScopeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@

interface ContextStorageScopeInterface extends ScopeInterface, ArrayAccess
{
/**
* Returns the context associated with this scope.
*
* @return ContextInterface associated context
*/
public function context(): ContextInterface;

/**
Expand Down
51 changes: 51 additions & 0 deletions src/Context/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,52 @@
# OpenTelemetry Context

Immutable execution scoped propagation mechanism, for further details see [opentelemetry-specification][1].

## Installation

```shell
composer require open-telemetry/context
```

## Usage

### Implicit propagation

```php
$context = Context::getCurrent();
// modify context
$scope = $context->activate();
try {
// run within new context
} finally {
$scope->detach();
}
```

It is recommended to use a `try-finally` statement after `::activate()` to ensure that the created scope is properly `::detach()`ed.

## Async applications

### Fiber support

Requires `PHP >= 8.1`, `ext-ffi` and setting the environment variable `OTEL_PHP_FIBERS_ENABLED` to a truthy value. Additionally `vendor/autoload.php` has to be preloaded for non-CLI SAPIs if [`ffi.enable`](https://www.php.net/manual/en/ffi.configuration.php#ini.ffi.enable) is set to `preload`.

### Event loops

Event loops have to restore the original context on callback execution. A basic implementation could look like the following, though implementations should avoid keeping unnecessary references to arguments if possible:

```php
function bindContext(Closure $closure): Closure {
$context = Context::getCurrent();
return static function (mixed ...$args) use ($closure, $context): mixed {
$scope = $context->activate();
try {
return $closure(...$args);
} finally {
$scope->detach();
}
};
}
```

[1]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/README.md#context
5 changes: 4 additions & 1 deletion src/Context/ScopeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@

interface ScopeInterface
{
/** Already detached. */
public const DETACHED = 1 << (PHP_INT_SIZE << 3) - 1;
/** Execution context inactive. */
public const INACTIVE = 1 << (PHP_INT_SIZE << 3) - 2;
/** Not current context. */
public const MISMATCH = 1 << (PHP_INT_SIZE << 3) - 3;

/**
Expand All @@ -23,7 +26,7 @@ interface ScopeInterface
* @see self::INACTIVE
* @see self::MISMATCH
*
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/context/context.md#detach-context
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/README.md#detach-context
*/
public function detach(): int;
}
2 changes: 1 addition & 1 deletion src/Context/composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "open-telemetry/context",
"description": "Context implementation for OpenTelemetry PHP.",
"keywords": ["opentelemetry", "otel", "metrics", "tracing", "logging", "apm", "context"],
"keywords": ["opentelemetry", "otel", "context"],
"type": "library",
"license": "Apache-2.0",
"authors": [
Expand Down

0 comments on commit 215731f

Please sign in to comment.