---
title: "OP-02: Run the default ping pipeline for one target"
summary: The default-interface-method orchestration implementers inherit from IPingableService.
status: draft
owner: SAIF Platform Team
last_reviewed: 2026-10-02
library: SAIF.NetCore.PingableService
reference_type: package
operation_id: OP-02
trigger: Invoked from OP-01 step 5 for each resolved pingable target; may also be called directly by consumers.
---

# OP-02: Run the default ping pipeline for one target

| Field | Value |
| --- | --- |
| Operation ID | OP-02 |
| Trigger | Invoked once per target from [OP-01](op-01-ping-the-api.md) step 5; implementers may also call `PingAsync` directly. |
| Inputs | `guid` (run id), `logger` (`ISaifLogService`, may be `null`). |
| Outputs | A `Task` that completes successfully, or faults. In the common case the fault carries the original exception thrown by `Ping`, but an `IsThrowablePingError`/`OnPingFailure` override that itself throws replaces it, and an `OnPingSuccess` override that throws can fault the task even when `Ping` succeeded or its failure was swallowed — see Failure and edge-case behavior below. |
| Primary components | `IPingableService.PingAsync` (default interface implementation) |
| Entry point | `IPingableService.PingAsync` |

## Steps
1. Inside `Task.Run`, execute `Ping(guid, logger)`; the default implementation is a no-op, and implementers re-implement it to test connectivity or other health signals ([BR-07](../business-rules.md#br-07-ping-exceptions-are-failures-unless-vetoed)). If an implementer re-implements `PingAsync` itself instead of `Ping`, none of these steps apply.*
2. On exception, call `IsThrowablePingError(guid, ex, logger)`; the default returns `true` ([BR-07](../business-rules.md#br-07-ping-exceptions-are-failures-unless-vetoed)).
3. If throwable, call `OnPingFailure(guid, ex, logger)` (default no-op); provided `OnPingFailure` completes without itself throwing, the `catch` block's bare `throw;` then rethrows the original exception unchanged to fault the task ([BR-07](../business-rules.md#br-07-ping-exceptions-are-failures-unless-vetoed)). If `OnPingFailure` itself throws, that new exception propagates from within the `catch` block instead, and `throw;` is never reached — the original exception is not rethrown at all.*
4. If not throwable, the exception is swallowed and execution falls through to step 5 ([BR-08](../business-rules.md#br-08-non-throwable-ping-errors-count-as-success)).
5. Call `OnPingSuccess(guid, logger)` (default no-op) — this runs both on a clean success and on a swallowed non-throwable failure ([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)).

## Process flow

```mermaid
flowchart TD
    A[PingAsync starts in Task.Run] --> B[Execute Ping - default no-op]
    B --> C{Exception thrown?}
    C -->|No| D[OnPingSuccess runs]
    C -->|Yes| E[IsThrowablePingError classifies]
    E --> F{Throwable?}
    F -->|Yes| G["OnPingFailure runs, then rethrow - task faults"]
    F -->|No| H[Exception swallowed]
    H --> D
```

## Failure and edge-case behavior
- `ISaifLogService` is only ever passed through to the hooks; the library itself never calls a member on it, so a `null` logger never causes a failure here.
- An implementer that overrides `PingAsync` directly bypasses this entire pipeline, including the `IsThrowablePingError`/`OnPingFailure`/`OnPingSuccess` hook contract.*
- The task does not necessarily fault with the original `Ping` exception: if `IsThrowablePingError` or `OnPingFailure` itself throws, that new exception propagates **instead of** the original one, not in addition to it — the `throw;` statement that would rethrow the original is never reached, so the original exception does not propagate at all once a hook (or the classifier) throws from within the `catch` block. Similarly, `OnPingSuccess` runs outside the `try`/`catch` entirely, so an override that throws faults the task with that new exception even on a clean success or a swallowed non-throwable failure.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [Service registration](../service-registration.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts.

## Sources
- `src/SAIF.NetCore.PingableService/SAIF.NetCore.PingableService/IPingableService.cs`
