Verbara.Sdk.Sessions 2.8.0

dotnet add package Verbara.Sdk.Sessions --version 2.8.0
                    
NuGet\Install-Package Verbara.Sdk.Sessions -Version 2.8.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Verbara.Sdk.Sessions" Version="2.8.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Verbara.Sdk.Sessions" Version="2.8.0" />
                    
Directory.Packages.props
<PackageReference Include="Verbara.Sdk.Sessions" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Verbara.Sdk.Sessions --version 2.8.0
                    
#r "nuget: Verbara.Sdk.Sessions, 2.8.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Verbara.Sdk.Sessions@2.8.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Verbara.Sdk.Sessions&version=2.8.0
                    
Install as a Cake Addin
#tool nuget:?package=Verbara.Sdk.Sessions&version=2.8.0
                    
Install as a Cake Tool

Verbara.Sdk.Sessions

Session Engine for the Verbara.Sdk ecosystem. Provides call session correlation, lifecycle state machines, and domain events for real-time telephony monitoring.

Features

  • CallSession - Models the full lifecycle of a call: Created, Dialing, Ringing, Queued, Connected, OnHold, Transferring, Conference, Completed, Failed (TimedOut is kept for sessions stored by earlier versions; since 2.7.0 no call ends in it)
  • CallSessionManager - Automatic session creation and correlation by LinkedId, with 4-tier O(1) indexing
  • Reconciliation sweep - Registered by AddVerbaraSessions: when a held call is older than DialingTimeout, it checks the held calls against Asterisk's channel snapshot and ends, as a reload ends it, a call whose channels Asterisk no longer reports. It never ends a call for its age. See the migration guide
  • Domain Events - Observable stream of CallStarted, CallConnected, CallQueued, CallHeld, CallEnded, CallFailed events
  • Extension Points - Abstract base classes for custom routing (CallRouterBase), agent selection (AgentSelectorBase), and persistence (SessionStoreBase)
  • SessionMetrics - System.Diagnostics.Metrics counters for sessions created, completed and failed (sessions.timed_out and sessions.orphaned are still published, and no longer incremented since 2.7.0)
  • Resident-count gauges - sessions.active (calls in progress) and sessions.retained (ended calls still held), published by each CallSessionManager under the Verbara.Sdk.Sessions meter name and withdrawn when it is disposed

Quick Start

services.AddVerbara(options => { /* AMI config */ });
services.AddVerbaraSessions(options =>
{
    options.InboundContextPatterns = ["from-external"];
    options.OutboundContextPatterns = ["from-internal"];
});

var sessionManager = app.Services.GetRequiredService<ICallSessionManager>();
sessionManager.Events.Subscribe(evt => Console.WriteLine(evt));

Queue metrics

IQueueSessionTracker keeps one QueueSession per queue. Its counters cover a rolling window (SessionOptions.QueueMetricsWindow, 30 minutes by default, from WindowStart); CallsWaiting is the present moment and is not reset by a new window. The unit is the queue visit: a caller's join, until the queue connects it or it leaves. A caller the queue puts back (a dialplan that loops into Queue() again) makes a new visit each time. Each visit is counted when Asterisk reports what happened to it.

Counter What it counts
CallsOffered Visits that started: one per join.
CallsAnswered Visits the queue connected to a member (AgentConnect).
CallsAbandoned Visits app_queue counts abandoned, as its own Abandoned: the caller hung up while waiting, or the queue let it go without a connection — its timeout, the queue emptying, a withdrawal, a redirect. Counted at app_queue's abandon report (QueueCallerAbandon), just before the caller's leave. Includes CallsTimedOut. A caller that leaves with the queue's exit key is not abandoned: Asterisk counts it neither answered nor abandoned, and so does the tracker.
CallsTimedOut The part of CallsAbandoned that Queue()'s own timeout ended (QUEUESTATUS = TIMEOUT). Needs the dialplan class, below; without it, 0.
CallsAbandoned − CallsTimedOut Callers that hung up, or that the queue let go for another reason.
CallsWaiting Callers in the queue now. Asterisk's leave ends the wait, at every exit: a connection, a hang-up, a timeout, an emptied queue, a withdrawal, a redirect or a key.
CallsWithinSla, TotalWaitTime, MinWaitTime, MaxWaitTime Answered visits only, each wait from the visit's start to its connection.

What changed after 2.6.1. CallsTimedOut was never counted and now follows Asterisk's EXITWITHTIMEOUT. CallsWaiting dropped only when the caller was connected, hung up or joined again; it now drops at the leave. CallsAbandoned was counted when the caller hung up or joined again, and included key exits; it now moves at app_queue's abandon report and excludes them, so CallsAbandoned and AbandonRate are lower by the key exits. Measured 2026-10-03 on Asterisk 20.20.1, 22.9.0 and 23.4.1, 320 calls per version over every way of leaving a queue: after each call (each burst of ten, for the bursts), CallsAbandoned moved by app_queue's Abandoned and CallsTimedOut by its EXITWITHTIMEOUT count, and CallsWaiting equalled app_queue's Calls 700 ms after each of the 140 leaves sampled per version.

CallsTimedOut needs the dialplan class

app_queue reports a timeout only by setting QUEUESTATUS on the caller's channel, which Asterisk sends as a VarSet event, and only to an AMI user whose read includes dialplan (read = all includes it). Without it nothing breaks: a timed-out visit is still counted in CallsAbandoned, and CallsTimedOut stays 0. The class carries every dialplan variable assignment and extension step, so it is not free: measured on a test dialplan, 44 % to 51 % of all the events a read = all user received. Behind the manager.conf filter in Missing events, which passes only the QUEUESTATUS the tracker needs, it cost 1.28 % more bytes than no dialplan at all.

A timeout that happens while the AMI connection is down is not counted in CallsTimedOut; the visit is still counted abandoned. When a metrics window ends between a visit's abandon report and its QUEUESTATUS (a moment apart), the two land in different windows.

The key exit needs an unbroken event stream

A key exit is a leave with no abandon report before it. The tracker can tell it from an abandon whose report it missed only while it has lost no event since the visit started. After a reconnect, or after the AMI connection's event buffer dropped an event (ami.events.dropped, reason=buffer_full), a leave with no report is counted abandoned when the caller joins a queue again or hangs up, unless the queue connects it first. Over an IAmiConnection other than AmiConnection only reconnects are seen.

A caller whose leave fell inside an outage stops counting as waiting when the reload's queue snapshot (QueueStatus) completes without it, and is counted abandoned there; a reload whose snapshot did not complete closes nothing. An answer that happened during the outage cannot be observed, so such a visit counts abandoned too. Visits that both started and ended inside an outage are not seen at all.

Rates

Rate Formula When nothing was offered
ServiceLevel CallsWithinSla / CallsOffered × 100 100
AbandonRate CallsAbandoned / CallsOffered × 100 (timeouts in, key exits out) 0
AnswerRate CallsAnswered / CallsOffered × 100 0
AvgWaitTime TotalWaitTime / CallsAnswered zero

ServiceLevel is not app_queue's. app_queue's ServiceLevelPerf divides the calls answered within its servicelevel by the answered calls, and ServiceLevelPerf2 divides the calls answered or abandoned within it by the answered and abandoned calls. On a queue whose callers all time out, the three read 0 %, 0 % and 100 %. Compare ServiceLevel with another reading of the same formula, and set SessionOptions.SlaThreshold (20 s by default) to the queue's servicelevel when you compare it with Asterisk's.

Over a custom session manager

The tracker reads Asterisk's leave, abandon report and QUEUESTATUS through the SDK's own CallSessionManager. Over another ICallSessionManager it reads the domain events only: a visit ends at its connection, at the caller's next join or at its hang-up, abandoned unless connected (key exits included), and no timeout is counted.

Custom Persistence

public class PostgresSessionStore : SessionStoreBase
{
    public override ValueTask SaveAsync(CallSession session, CancellationToken ct) { /* ... */ }
    public override ValueTask<CallSession?> GetAsync(string sessionId, CancellationToken ct) { /* ... */ }
}

services.AddSingleton<SessionStoreBase, PostgresSessionStore>();
services.AddVerbaraSessions();
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on Verbara.Sdk.Sessions:

Package Downloads
Verbara.Sdk.Hosting

Verbara.Sdk.Hosting - DI extensions and meta-package referencing all Verbara Sdk sub-packages

Verbara.Sdk.Sessions.Postgres

Verbara.Sdk.Sessions.Postgres - Postgres-backed SessionStoreBase for multi-instance deployments. Ships PostgresSessionStore + fluent UsePostgres(...) registration for Verbara.Sdk.Sessions. AOT-safe (source-generated JSON only, raw Npgsql parameterized SQL).

Verbara.Sdk.Sessions.Redis

Verbara.Sdk.Sessions.Redis - Redis-backed SessionStoreBase for horizontal scale-out. Ships RedisSessionStore + fluent UseRedis(...) registration for Verbara.Sdk.Sessions. AOT-safe (source-generated JSON only).

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.8.0 0 10/9/2026
2.7.0 539 10/3/2026
2.6.1 494 9/30/2026
2.6.0 728 9/24/2026
2.5.3 629 9/13/2026
2.5.2 284 9/13/2026
2.5.1 305 9/12/2026
2.5.0 382 8/25/2026
2.4.0 2,004 7/27/2026
2.3.2 699 7/20/2026
2.3.1 325 7/14/2026
2.3.0 444 7/6/2026
2.2.1 963 5/23/2026
2.2.0 176 5/20/2026
2.1.2 177 5/8/2026
2.1.1 152 5/7/2026
2.1.0 3,420 5/7/2026
2.0.0 158 5/6/2026