---
title: Operations and processes
summary: Catalog of operations performed by this library and their process flows.
status: draft
owner: SAIF Platform Team
last_reviewed: 2026-10-02
library: SAIF.NetCore.PingableService
reference_type: package
---

# Operations and processes

This library performs 5 distinct operations spanning the anonymous ping request itself, the default per-target ping pipeline, registration-time DI wiring, controller discovery, and failure reporting.

## Operation catalog

| ID | Operation | Primary component | Business rules |
| --- | --- | --- | --- |
| OP-01 | [Ping the API](operations/op-01-ping-the-api.md) | `PingableController.Get` | [BR-01](business-rules.md#br-01-anonymous-access-to-ping-endpoint), [BR-02](business-rules.md#br-02-run-id-defaults-to-a-generated-guid), [BR-03](business-rules.md#br-03-ping-set-defined-by-di-registration-and-mvc-application-parts), [BR-04](business-rules.md#br-04-concurrent-ping-execution-via-task.whenall), [BR-05](business-rules.md#br-05-resolution-and-construction-failures-count-as-ping-failures), [BR-06](business-rules.md#br-06-pingserviceexception-is-not-wrapped-twice), [BR-09](business-rules.md#br-09-successful-run-returns-200-with-run-id) |
| OP-02 | [Run the default ping pipeline for one target](operations/op-02-default-ping-pipeline.md) | `IPingableService.PingAsync` | [BR-07](business-rules.md#br-07-ping-exceptions-are-failures-unless-vetoed), [BR-08](business-rules.md#br-08-non-throwable-ping-errors-count-as-success), [BR-09](business-rules.md#br-09-successful-run-returns-200-with-run-id) |
| OP-03 | [Register a pingable service](operations/op-03-register-pingable-service.md) | `IServiceCollectionExtensions.AddPingable*` | [BR-11](business-rules.md#br-11-pingable-registration-requires-tservice-to-extend-ipingableservice), [BR-15](business-rules.md#br-15-ipingableservice-resolution-casts-through-tservice-registration) |
| OP-04 | [Enable the ping route and discover pingable controllers](operations/op-04-enable-route-and-discover-controllers.md) | `MvcBuilderExtensions.WithPingableController`, `ControllerRetriever` | [BR-03](business-rules.md#br-03-ping-set-defined-by-di-registration-and-mvc-application-parts), [BR-13](business-rules.md#br-13-withpingablecontroller-enables-route-and-controller-discovery), [BR-14](business-rules.md#br-14-controller-discovery-requires-controllers-registered-as-services) |
| OP-05 | [Raise a ping failure](operations/op-05-raise-ping-failure.md) | `PingServiceException` constructor | [BR-10](business-rules.md#br-10-ping-failure-returns-500-with-run-id-and-message) |

## Process flow diagram

The following diagram traces a single `GET /Ping` request from the host's MVC pipeline through target resolution, concurrent pinging, and failure reporting.

```mermaid
flowchart TD
    A[GET /Ping request] --> B[Construct PingableController - OP-01 step 1]
    B --> C[Default guid if absent]
    C --> D[Resolve DI-registered IPingableService targets]
    D --> E["Discover + resolve pingable controllers - OP-04"]
    E --> F[Start all PingAsync concurrently - OP-02]
    F --> G{Task.WhenAll}
    G -->|all awaited tasks succeed| H[Return 200 OK with guid]
    G -->|faulted or canceled| I[Flatten/wrap failure into PingServiceException - OP-05]
    I --> J[Throw 500 PingServiceException]
    J --> K["DynamicErrorHandler -> IErrorHandler formats response,<br>if registered"]
```

## Failure and edge-case behavior
- Any constructor or dependency-resolution failure for a pingable service or controller is treated as a ping failure and surfaces as a 500 ([BR-05](business-rules.md#br-05-resolution-and-construction-failures-count-as-ping-failures)).
- `IPingableService.PingAsync`'s default implementation lets an implementer veto a failure via `IsThrowablePingError`, converting what would otherwise be a failing ping into a successful one ([BR-08](business-rules.md#br-08-non-throwable-ping-errors-count-as-success)); an `OnPingFailure` or `IsThrowablePingError` override that itself throws replaces the original `Ping` exception with its own, and an `OnPingSuccess` override that throws can fault the task even after a clean or swallowed `Ping` — see [OP-02](operations/op-02-default-ping-pipeline.md).
- `WithPingableController()` is the supported convenience path for enabling the `/Ping` route and controller discovery together; without it (or an equivalent explicit application-part and `IControllerRetriever` registration), `/Ping` is not routed at all ([BR-13](business-rules.md#br-13-withpingablecontroller-enables-route-and-controller-discovery)).
- Pingable *controllers* are resolved from DI by concrete type, so the controller-discovery channel additionally requires the host to call `AddControllersAsServices()` (or an equivalent explicit registration) only when such controllers exist; otherwise `GetService(type)` returns `null` and the resulting `NullReferenceException` surfaces as a 500 ([BR-14](business-rules.md#br-14-controller-discovery-requires-controllers-registered-as-services)).
- A faulted `Task.WhenAll` (one or more awaited pings failed), a canceled `Task.WhenAll` (rethrown when `whenAll.Exception` is null), and a synchronous resolution/reflection failure are three distinct failure paths, not one — see [OP-01](operations/op-01-ping-the-api.md) steps 6–7.
- Converting a thrown `PingServiceException` into a formatted HTTP 500 response depends on the host having `DynamicErrorHandler` (and its injected `IErrorHandler`) registered, which `BaseApiStartup`-derived hosts do by default; without it, ASP.NET Core's default unhandled-exception handling still yields a 500, but without SAIF formatting.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Business rules](business-rules.md)
- [Security and authorization](security-authorization.md)
- [Service registration](service-registration.md)
- [API reference](api/index.md)

## Sources
- `src/SAIF.NetCore.PingableService/SAIF.NetCore.PingableService/Controllers/PingableController.cs`
- `src/SAIF.NetCore.PingableService/SAIF.NetCore.PingableService/IPingableService.cs`
- `src/SAIF.NetCore.PingableService/SAIF.NetCore.PingableService/Extensions/IServiceCollectionExtensions.cs`
- `src/SAIF.NetCore.PingableService/SAIF.NetCore.PingableService/Extensions/MvcBuilderExtensions.cs`
- `src/SAIF.NetCore.PingableService/SAIF.NetCore.PingableService/Services/ControllerRetriever.cs`
- `src/SAIF.NetCore.PingableService/SAIF.NetCore.PingableService/Exceptions/PingServiceException.cs`
- `src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/Middleware/DynamicErrorHandler.cs`
- `src/SAIF.NetCore.ErrorHandler/SAIF.NetCore.ErrorHandler/SAIF.NetCore.ErrorHandler/ErrorHandler.cs`
