# पुनः उपयोगीय अल्पावधि निष्पादन लाइब्रेरी का निर्माण

<!--category-- ASP.NET, Architecture, Systems Design, Async, DI -->
<datetime class="hidden">2025-12-12T14:00</datetime>

में **[भाग 1: आग और Don *बिलकुल* भूलें](/blog/fire-and-dont-quite-forget-ephemeral-execution)**हम अल्पावधि निष्पादन के पीछे सिद्धांत का पता लगा।

यह अनुच्छेद उस पैटर्न को एक पुनः उपयोग योग्य लाइब्रेरी में बदलता है जिसे आप किसी भी .NET परियोजना में डाल सकते हैं

## नुगेट

यह अब mostlylucid.ephemerals Nuget पैकेज में भी है [से अधिक 20 mostlylucid.ephemerals पैटर्न और 'atoms](https://www.nuget.org/packages?q=mostlylucid.ephemeral&includeComputedFrameworks=true&prerel=true&sortby=created-desc).

[![न्यूगेटGenericName](https://img.shields.io/nuget/v/mostlylucid.ephemeral.svg)](https://www.nuget.org/packages/mostlylucid.ephemeral)
[![लाइसेंस](https://img.shields.io/badge/license-Unlicense-blue.svg)](../../UNLICENSE)

## स्रोत फ़ाइलें

पूर्ण स्रोत कोड में है [mostlylucid.atoms GitHub रिपोजिटरी](https://github.com/scottgal/mostlylucid.atoms)

[TOC]

---


## पूर्व और बाद

यहाँ क्या हम प्रतिस्थापन कर रहे हैं

```csharp
// ❌ Before: Fire-and-forget black hole
_ = Task.Run(() => ProcessAsync(item));
// No visibility. No debugging. No idea if it worked.

// ❌ Or: Blocking everything
await ProcessAsync(item);  // Hope you like waiting...
```

और हम क्या बना रहे हैं

```csharp
// ✅ After: Trackable, bounded, debuggable
await coordinator.EnqueueAsync(item);

// Instant visibility
Console.WriteLine($"Pending: {coordinator.PendingCount}");
Console.WriteLine($"Active: {coordinator.ActiveCount}");
Console.WriteLine($"Failed: {coordinator.TotalFailed}");

// Full operation history
var snapshot = coordinator.GetSnapshot();
var failures = coordinator.GetFailed();
```

Same async execution. Complete observabilityM SK1 No user data retained.

---


## त्वरित प्रारंभ

सबसे आम पैटर्न - एक समन्वयक को डीआई में पंजीकृत करता है और इसे इंजेक्शन करता है

```csharp
// Program.cs
services.AddEphemeralWorkCoordinator<TranslationRequest>(
    async (request, ct) => await TranslateAsync(request, ct),
    new EphemeralOptions { MaxConcurrency = 8 });

// Your service
public class TranslationService(EphemeralWorkCoordinator<TranslationRequest> coordinator)
{
    public async Task TranslateAsync(TranslationRequest request)
    {
        await coordinator.EnqueueAsync(request);
        // Returns immediately - work happens in background
    }

    public object GetStatus() => new
    {
        pending = coordinator.PendingCount,
        active = coordinator.ActiveCount,
        completed = coordinator.TotalCompleted,
        failed = coordinator.TotalFailed
    };
}
```

---


## मुझे कौन सी चर की जरूरत है

```text
┌─────────────────────────────────────────────────────────────────┐
│                    DECISION TREE                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Processing a collection once?                                  │
│  └─► EphemeralForEachAsync<T> (ParallelEphemeral.cs)            │
│                                                                 │
│  Need a long-lived queue that accepts items over time?          │
│  └─► EphemeralWorkCoordinator<T>                                │
│                                                                 │
│  Need per-entity ordering (user commands, tenant jobs)?         │
│  └─► EphemeralKeyedWorkCoordinator<TKey, T>                     │
│                                                                 │
│  Need to capture results (fingerprints, summaries)?             │
│  └─► EphemeralResultCoordinator<TInput, TResult>                │
│                                                                 │
│  Need multiple coordinators with different configs?             │
│  └─► IEphemeralCoordinatorFactory<T> (like IHttpClientFactory)  │
│                                                                 │
│  Need dynamic concurrency adjustment at runtime?                │
│  └─► Set EnableDynamicConcurrency = true, call SetMaxConcurrency│
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
```

---


## कॉन्फ़िगरेशन ऑब्जेक्ट

से [अल्पावधि विकल्प](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/EphemeralOptions.cs):

```csharp
public sealed class EphemeralOptions
{
    // Concurrency control
    public int MaxConcurrency { get; init; } = Environment.ProcessorCount;
    public int MaxConcurrencyPerKey { get; init; } = 1;
    public bool EnableDynamicConcurrency { get; init; } = false;

    // Window management
    public int MaxTrackedOperations { get; init; } = 200;
    public TimeSpan? MaxOperationLifetime { get; init; } = TimeSpan.FromMinutes(5);

    // Fair scheduling (keyed coordinator)
    public bool EnableFairScheduling { get; init; } = false;
    public int FairSchedulingThreshold { get; init; } = 10;

    // Signal-reactive processing
    public IReadOnlySet<string>? CancelOnSignals { get; init; }
    public IReadOnlySet<string>? DeferOnSignals { get; init; }
    public int MaxDeferAttempts { get; init; } = 10;
    public TimeSpan DeferCheckInterval { get; init; } = TimeSpan.FromMilliseconds(100);

    // Signal infrastructure
    public SignalSink? Signals { get; init; }
    public SignalConstraints? SignalConstraints { get; init; }
    public Action<SignalEvent>? OnSignal { get; init; }

    // Async signal handling
    public Func<SignalEvent, CancellationToken, Task>? OnSignalAsync { get; init; }
    public int MaxConcurrentSignalHandlers { get; init; } = 4;
    public int MaxQueuedSignals { get; init; } = 1000;

    // Observability
    public Action<IReadOnlyCollection<EphemeralOperationSnapshot>>? OnSample { get; init; }
}
```

### प्रमुख डिजाइन निर्णय

- **अधिकतम प्रतियोगिता** सीपीयू गणना के लिए डिफ़ॉल्ट्स - सीपी यू के लिए विवेकपूर्ण
- **गतिक प्रतियोगिता सक्षम करें** रनटाइम समायोजन सक्षम करता है `SetMaxConcurrency()` - एक पसंदीदा गेट के बजाय उपयोग करता है `SemaphoreSlim`.
- **रद्दOnSignals** समन्वयकों को संकेत दें -प्रतिक्रियात्मक - वे परिवेश प्रणाली स्थिति के प्रति प्रतिक्रिया करते हैं | ( | पैटर्न मिलान समर्थन `*`/`?`comma सूची
- **पर हस्ताक्षर** एकsync फ़ेन के लिए समक्रमी है `SignalDispatcher` या `AsyncSignalProcessor` हैंडलर के अंदर
- **सिग्नल अवरोध** चक्र पता लगाने और गहराई सीमाओं के साथ अनन्त संकेत लूपों को रोकता है

---


## स्नैपशॉट रिकार्ड्स

से [स्न्यापसॉट](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/Snapshots.cs):

```csharp
public sealed record EphemeralOperationSnapshot(
    long Id,
    DateTimeOffset Started,
    DateTimeOffset? Completed,
    string? Key,
    bool IsFaulted,
    Exception? Error,
    TimeSpan? Duration,
    IReadOnlyList<string>? Signals = null,
    bool IsPinned = false)
{
    public bool HasSignal(string signal) => Signals?.Contains(signal) == true;
}

// For result-capturing coordinators
public sealed record EphemeralOperationSnapshot<TResult>(
    long Id,
    DateTimeOffset Started,
    DateTimeOffset? Completed,
    string? Key,
    bool IsFaulted,
    Exception? Error,
    TimeSpan? Duration,
    TResult? Result,
    bool HasResult,
    IReadOnlyList<string>? Signals = null,
    bool IsPinned = false);
```

यह है **सिर्फ मेटाडेटा**नोट करें क्या *नहीं* यहाँ

- कोई पेलोड नहीं
- कोई इनपुट डाटा नहीं
- कोई उपयोक्ता सामग्री नहीं

बस जवाब देने के लिए पर्याप्त है।

---


## यह कैसे अन्य दृष्टिकोणों से तुलना करता है

आप को समांतर काम करने के कई तरीके देते हैं

### समांतर

```csharp
await Parallel.ForEachAsync(items,
    new ParallelOptions { MaxDegreeOfParallelism = 4 },
    async (item, ct) => await ProcessAsync(item, ct));
```

**के लिए सर्वोत्तम**: संग्रहों का सरल समानांतर प्रक्रमण जहां आप नहीं कर रहे हैं

**उसमें क्या कमी है?**:

- कोई ऑपरेशन ट्रैकिंग नहीं
- कोई per-key अनुक्रमिक निष्पादन नहीं
- क्या चला रहा है में कोई दृश्यता नहीं

**जब अल्पकालिक का उपयोग करें**: आपको त्रुटिमोचन की जरूरत है/अनुमाननीयताM SK2 प्रतिMSC3 कुंजी क्रमादेशन , या संकेत

### टीपीएल डाटाफ्लो

```csharp
var block = new ActionBlock<T>(
    async item => await ProcessAsync(item),
    new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 4 });

foreach (var item in items)
    block.Post(item);

block.Complete();
await block.Completion;
```

**के लिए सर्वोत्तम**शाखाओं सहित जटिल डेटा प्रवाह पाइपलाइन

**यह क्या अच्छा करता है**:

- समृद्ध पाइपलाइन संरचना (लिंक ब्लॉक्स एक साथ
- निर्माणित-बैचिंग में,परिवर्तन M SK2 प्रसारण
- पीठ के साथ बंधित क्षमता-प्रेरणा

**जब TPL डाटाफ्लो का उपयोग करें**आपको जटिल पाइपलाइन टोपोलॉजी की जरूरत है

**जब अल्पकालिक का उपयोग करें**You need operation tracking, simpler API, or signal

### प्रणाली.Threading.Channels

```csharp
var channel = Channel.CreateBounded<T>(100);

// Producer
foreach (var item in items)
    await channel.Writer.WriteAsync(item);
channel.Writer.Complete();

// Consumer (multiple workers)
var workers = Enumerable.Range(0, 4).Select(async _ =>
{
    await foreach (var item in channel.Reader.ReadAllAsync())
        await ProcessAsync(item);
});
await Task.WhenAll(workers);
```

**के लिए सर्वोत्तम**: उत्पादक\-\consumer patterns where you control both sides

**यह क्या अच्छा करता है**:

- उत्कृष्ट निष्पादन
- बार्डन चैनलों के माध्यम से दबाव
- उत्पादकों और उपभोक्ताओं का विभाजन

**चैनल का उपयोग करें जब**: आप\ '\ आप अनुकूल अवसंरचना का निर्माण कर रहे हैं और अधिकतम नियंत्रण की आवश्यकता है

**जब अल्पकालिक का उपयोग करें**You want operation tracking and observability without the boilerplate

### पोलीCity name (optional, probably does not need a translation)

```csharp
var policy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetryAsync(3, attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)));

await policy.ExecuteAsync(() => ProcessAsync(item));
```

**के लिए सर्वोत्तम**: प्रतिरोध नीतियां

**पॉली का उपयोग करें जब**: आप को व्यक्तिगत कॉलों के बारे में लचीलापन की जरूरत है

**जब अल्पकालिक का उपयोग करें**आप को पर्यावरण जागरूकता के साथ अनेक ऑपरेशनों में समन्वय की जरूरत है

**इनका संयोजन करें**: per के लिए अपने अल्पकालीन कार्य शरीर में पॉली का उपयोग करें

### massTransit / NServiceBus

**के लिए सर्वोत्तम**स्थायी कतारों के साथ सेवाओं में वितरित संदेश

**जब संदेश बस का उपयोग करें**कार्य को प्रक्रिया पुनः आरंभ होने से बचना चाहिए

**जब अल्पकालिक का उपयोग करें**कार्य में है

### तुलना तालिका

दृष्टिकोण | सीमाबद्ध | ट्रैकिंग | प्रति SSK4 कुंजी S| संकेतों | | स्व | SSK7 | क्लेनिंग | | | जटिलता | |
|----------|:-------:|:--------:|:-------:|:-------:|:-------------:|:----------:|
| `Parallel.ForEachAsync` | | ✅ | || |
TPL डेटा प्रवाह
चैनल
Polly | NM SK2A | SSK4 \| N\/A
पृष्ठभूमि सेवाएं
|MassTransit/NServiceBus | | | \ ✅ |
| **अल्पकालीन पुस्तकालय** 0 ± ± 1 ± 2 ± 3 ± 4 ± 5 ± 6 ± 7 ± 8 ± 9 ± 10 ± कम

---


## अल्पावधि के लिए प्रत्येक अतुल्यकालिक: एक

से [समांतर दीर्घकालिक](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/ParallelEphemeral.cs):

```csharp
// Simple parallel processing with tracking
await items.EphemeralForEachAsync(
    async (item, ct) => await ProcessAsync(item, ct),
    new EphemeralOptions { MaxConcurrency = 8 });

// With keyed execution (per-user sequential)
await commands.EphemeralForEachAsync(
    cmd => cmd.UserId,  // Key selector
    async (cmd, ct) => await ExecuteCommandAsync(cmd, ct),
    new EphemeralOptions
    {
        MaxConcurrency = 32,
        MaxConcurrencyPerKey = 1  // Sequential per user
    });
```

### क्यों कुंजीकृत पाइपलाइन महत्वपूर्ण हैं

उपयोक्ता कमांडों को प्रक्रमित करने की कल्पना करें

- उपयोक्ता ए कमांड भेजता है
- उपयोक्ता बी कमांड भेजता है

बिना कुंजी लगाये, यह निष्पादित हो सकता है जैसेः

के साथ `MaxConcurrencyPerKey = 1`:

- उपयोक्ता A के कमांड क्रमानुसार निष्पादित होते हैं
- उपयोक्ता B के कमांड क्रम में निष्पादित होते हैं
- लेकिन ए और बी समानांतर में चला सकते हैं

यह है **per-entity sequential, globally parallel** उन प्रणालियों के लिए महत्वपूर्ण है जहां एक इकाई के भीतर आदेश महत्वपूर्ण है

---


## कार्य समन्वयक

से [अल्पकालीन कार्य समन्वयक.cs](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/EphemeralWorkCoordinator.cs):

```csharp
await using var coordinator = new EphemeralWorkCoordinator<TranslationRequest>(
    async (request, ct) => await TranslateAsync(request, ct),
    new EphemeralOptions
    {
        MaxConcurrency = 8,
        MaxTrackedOperations = 500,
        EnableDynamicConcurrency = true  // Allow runtime adjustment
    });

// Enqueue items over time
await coordinator.EnqueueAsync(new TranslationRequest("Hello", "es"));

// Check status anytime
Console.WriteLine($"Pending: {coordinator.PendingCount}");
Console.WriteLine($"Active: {coordinator.ActiveCount}");

// Get snapshots
var snapshot = coordinator.GetSnapshot();
var running = coordinator.GetRunning();
var failed = coordinator.GetFailed();
var completed = coordinator.GetCompleted();

// Control flow
coordinator.Pause();   // Stop pulling new work
coordinator.Resume();  // Continue

// Adjust concurrency at runtime (requires EnableDynamicConcurrency)
coordinator.SetMaxConcurrency(16);

// Pin important operations to survive eviction
coordinator.Pin(operationId);
coordinator.Unpin(operationId);
coordinator.Evict(operationId);

// When done
coordinator.Complete();
await coordinator.DrainAsync();
```

### IAsyncEnumerable के साथ सतत प्रवाह

```csharp
await using var coordinator = EphemeralWorkCoordinator<Message>.FromAsyncEnumerable(
    messageStream,  // IAsyncEnumerable<Message>
    async (msg, ct) => await ProcessMessageAsync(msg, ct),
    new EphemeralOptions { MaxConcurrency = 16 });

await coordinator.DrainAsync();
```

---


## कुंजीकृत समन्वयक

से [अल्पकालिक कुंजीकृत कार्य समन्वयक.cs](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/EphemeralKeyedWorkCoordinator.cs):

```csharp
await using var coordinator = new EphemeralKeyedWorkCoordinator<string, Command>(
    cmd => cmd.UserId,  // Key selector
    async (cmd, ct) => await ExecuteCommandAsync(cmd, ct),
    new EphemeralOptions
    {
        MaxConcurrency = 32,
        MaxConcurrencyPerKey = 1,      // Per-user sequential
        EnableFairScheduling = true,   // Prevent hot user starvation
        FairSchedulingThreshold = 10   // Reject if user has 10+ pending
    });

// TryEnqueue returns false if fair scheduling rejects
if (!coordinator.TryEnqueue(hotUserCommand))
{
    await DeferCommandAsync(hotUserCommand);
}

// Per-key visibility
var pendingForUser = coordinator.GetPendingCountForKey("user-123");
var opsForUser = coordinator.GetSnapshotForKey("user-123");
```

---


## परिणाम-कलन समन्वयक

से [अल्पकालीन परिणाम समन्वयक.cs](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/EphemeralResultCoordinator.cs):

```csharp
await using var coordinator = new EphemeralResultCoordinator<SessionInput, SessionResult>(
    async (input, ct) =>
    {
        var fingerprint = await ComputeFingerprintAsync(input.Events, ct);
        return new SessionResult(fingerprint, input.Events.Length);
    },
    new EphemeralOptions { MaxConcurrency = 16 });

await coordinator.EnqueueAsync(session);
coordinator.Complete();
await coordinator.DrainAsync();

// Get just the results (no metadata)
var results = coordinator.GetResults();

// Get snapshots with results + metadata
var snapshots = coordinator.GetSnapshot();

// Get base snapshots without results (privacy-safe)
var baseSnapshots = coordinator.GetBaseSnapshot();

// Filter by success/failure
var successful = coordinator.GetSuccessful();
var failed = coordinator.GetFailed();
```

---


## प्रतियोगिता नियंत्रण

से [कंकोरेन्टी गेट्स](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/ConcurrencyGates.cs):

लाइब्रेरी दो समवर्ती नियंत्रण तंत्र उपलब्ध कराता है

### स्थिर प्रतियोगिता गेट (पूर्वनिर्धारित)

- द्वारा समर्थित `SemaphoreSlim`
- अधिकतम गर्म पथ निष्पादन
- रनटाइम पर समायोजन नहीं किया जा सकता है

### समायोजन योग्य प्रतियोगिता गेट

- मनपसंद कार्यान्वयन के साथ `Queue<WaiterEntry>`
- समर्थन `UpdateLimit()` रनटाइम पर
- के माध्यम से सक्षम `EnableDynamicConcurrency = true`

```csharp
// Dynamic concurrency adjustment
var coordinator = new EphemeralWorkCoordinator<T>(body,
    new EphemeralOptions
    {
        MaxConcurrency = 4,
        EnableDynamicConcurrency = true
    });

// Later, based on system load:
coordinator.SetMaxConcurrency(16);  // Scale up
coordinator.SetMaxConcurrency(2);   // Scale down
```

---


## फैक्टरी पैटर्न: नामित समन्वयक

से [निर्भरता इंजेक्शन](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/DependencyInjection.cs):

जैसे `IHttpClientFactory`आप नामित विन्यास पंजीकृत कर सकते हैं

```csharp
// Registration
services.AddEphemeralWorkCoordinator<TranslationRequest>("fast",
    async (request, ct) => await FastTranslateAsync(request, ct),
    new EphemeralOptions { MaxConcurrency = 32 });

services.AddEphemeralWorkCoordinator<TranslationRequest>("accurate",
    async (request, ct) => await AccurateTranslateAsync(request, ct),
    new EphemeralOptions { MaxConcurrency = 4 });

// Usage
public class TranslationService(IEphemeralCoordinatorFactory<TranslationRequest> factory)
{
    private readonly EphemeralWorkCoordinator<TranslationRequest> _fast =
        factory.CreateCoordinator("fast");
    private readonly EphemeralWorkCoordinator<TranslationRequest> _accurate =
        factory.CreateCoordinator("accurate");
}
```

### फैक्टरी गारंटी

1. **एक ही नाम = एक ही उदाहरण** - कॉल `CreateCoordinator("fast")` दो बार एक ही समन्वयक लौटाता है
2. **भिन्न नाम = भिन्न इंस्टैंस** - `"fast"` और `"accurate"` अलग समन्वयक प्राप्त करें
3. **अल्छी पैदा करना** - समन्वयक केवल पहली बार अनुरोध किए जाने पर बनाए जाते हैं
4. **कॉन्फ़िगरेशन वैधता** - एक पंजीकृत नहीं नाम की मांग करने से एक सहायक त्रुटि फेंकती है

---


## सिग्नल क्वेरी API

सभी समन्वयक अनुकूल संकेत क्वेरी विधि उपलब्ध कराते हैं

```csharp
// Get all signals
var signals = coordinator.GetSignals();

// Filter by key (zero-allocation)
var userSignals = coordinator.GetSignalsByKey("user-123");

// Filter by time range
var recentSignals = coordinator.GetSignalsSince(DateTimeOffset.UtcNow.AddMinutes(-5));
var rangeSignals = coordinator.GetSignalsByTimeRange(from, to);

// Filter by signal name or pattern
var rateSignals = coordinator.GetSignalsByName("rate-limit");
var httpSignals = coordinator.GetSignalsByPattern("http.*");

// Check existence (short-circuits on first match)
if (coordinator.HasSignal("rate-limit"))
    await ThrottleAsync();

if (coordinator.HasSignalMatching("error.*"))
    await AlertAsync();

// Count signals efficiently (no allocation)
var totalSignals = coordinator.CountSignals();
var errorCount = coordinator.CountSignals("error");
var httpCount = coordinator.CountSignalsMatching("http.*");
```

---


## उत्पादन अनुकूलन

### त्वरित आईडी निर्माण

से [अल्पकालीन आईडी जनरेटर.cs](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/EphemeralIdGenerator.cs):

```csharp
internal static class EphemeralIdGenerator
{
    private static long _counter;
    private static readonly long _processStart = Environment.TickCount64;
    private static readonly int _processId = Environment.ProcessId;

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static long NextId()
    {
        var counter = Interlocked.Increment(ref _counter);

        // Combine counter with process-unique seed
        Span<byte> buffer = stackalloc byte[24];
        BitConverter.TryWriteBytes(buffer, _processStart);
        BitConverter.TryWriteBytes(buffer.Slice(8), _processId);
        BitConverter.TryWriteBytes(buffer.Slice(16), counter);

        return unchecked((long)XxHash64.HashToUInt64(buffer));
    }
}
```

- **आवंटन** ( `stackalloc`)
- **थ्रेड** ( `Interlocked.Increment`)
- **प्रक्रियाओं में एकल** प्रक्रिया आईडी शामिल है
- **Non-अनुक्रमिक** (hash कान्टर को फैलाता है

### मेमोरी

समन्वयक ' को भंडारित नहीं करते `Task` संदर्भ - सिर्फ गणक

```csharp
private int _activeTaskCount;
private readonly TaskCompletionSource _drainTcs;

// In ExecuteItemAsync:
finally
{
    // Signal drain when last task completes AND channel iteration is done
    if (Interlocked.Decrement(ref _activeTaskCount) == 0 &&
        Volatile.Read(ref _channelIterationComplete))
    {
        _drainTcs.TrySetResult();
    }
}
```

### Per-Key Lock Cleanup

कुंजीयुक्त समन्वयक स्वचालित रूप से निष्क्रिय को साफ करता है per

```csharp
private sealed class KeyLock(SemaphoreSlim gate, int maxCount)
{
    public SemaphoreSlim Gate { get; } = gate;
    public int MaxCount { get; } = maxCount;
    public long LastUsedTicks = Environment.TickCount64;
}

// Cleanup runs periodically, removes locks idle > 60 seconds
```

---


## पूर्ण उदाहरण

```csharp
// Program.cs
var builder = WebApplication.CreateBuilder(args);

// Named coordinators
builder.Services.AddEphemeralWorkCoordinator<TranslationRequest>("fast",
    async (req, ct) => await FastTranslateAsync(req, ct),
    new EphemeralOptions { MaxConcurrency = 16 });

// Keyed coordinator for per-user commands
builder.Services.AddEphemeralKeyedWorkCoordinator<string, UserCommand>("commands",
    cmd => cmd.UserId,
    sp =>
    {
        var handler = sp.GetRequiredService<ICommandHandler>();
        return async (cmd, ct) => await handler.HandleAsync(cmd, ct);
    },
    new EphemeralOptions
    {
        MaxConcurrency = 32,
        MaxConcurrencyPerKey = 1,
        EnableFairScheduling = true,
        CancelOnSignals = new HashSet<string> { "system-overload" }
    });

var app = builder.Build();
```

```csharp
// Controller
[ApiController]
[Route("api")]
public class WorkController : ControllerBase
{
    private readonly EphemeralWorkCoordinator<TranslationRequest> _translator;
    private readonly EphemeralKeyedWorkCoordinator<string, UserCommand> _commands;

    public WorkController(
        IEphemeralCoordinatorFactory<TranslationRequest> translationFactory,
        IEphemeralKeyedCoordinatorFactory<string, UserCommand> commandFactory)
    {
        _translator = translationFactory.CreateCoordinator("fast");
        _commands = commandFactory.CreateCoordinator("commands");
    }

    [HttpPost("translate")]
    public async Task<IActionResult> Translate([FromBody] TranslationRequest request)
    {
        await _translator.EnqueueAsync(request);
        return Ok(new { pending = _translator.PendingCount });
    }

    [HttpPost("command")]
    public IActionResult SubmitCommand([FromBody] UserCommand command)
    {
        if (!_commands.TryEnqueue(command))
            return StatusCode(429, "Too many pending commands for this user");
        return Ok();
    }

    [HttpGet("status")]
    public IActionResult GetStatus() => Ok(new
    {
        translator = new
        {
            pending = _translator.PendingCount,
            active = _translator.ActiveCount,
            completed = _translator.TotalCompleted,
            failed = _translator.TotalFailed,
            hasRateLimit = _translator.HasSignal("rate-limit")
        },
        commands = new
        {
            pending = _commands.PendingCount,
            active = _commands.ActiveCount,
            errorCount = _commands.CountSignalsMatching("error.*")
        }
    });
}
```

---


## निष्कर्ष

हमने एक पूर्ण अल्पावधि निष्पादन लाइब्रेरी का निर्माण किया है

1. **`EphemeralForEachAsync`** ट्रैकिंग के साथ समांतर प्रक्रमण
2. **`EphemeralWorkCoordinator`** - लंबा
3. **`EphemeralKeyedWorkCoordinator`** - Per- निष्पादन निष्पक्ष अनुसूचना के साथ अस्तित्व क्रमिक
4. **`EphemeralResultCoordinator`** - परिणाम
5. **फैक्टरी पैटर्न** - नामित विन्यास जैसे `IHttpClientFactory`
6. **गतिशील समवर्तन** - समांतरता के रनटाइम समायोजन
7. **संकेत अवसंरचना** सिग्नल उत्सर्जन और क्वेरी

नमूना एक सुचारु जगह में बैठता है

- इससे अधिक देखने योग्य `Parallel.ForEachAsync`
- टीपीएल डाटाफ्लो से सरल
- कच्चे चैनलों से अधिक एकीकृत
- डिजाइन द्वारा सुरक्षित

**फायर**

---


## लिंक्स

- [भाग 1: आग और Don *बिलकुल* भूलें](/blog/fire-and-dont-quite-forget-ephemeral-execution) - सिद्धांत और पैटर्न
- [भाग 3: अल्पकालिक संकेत](/blog/ephemeral-signals) - परमाणुओं को एक संवेदन नेटवर्क में बदलना
- [सेमैफोरस्लिम दस्तावेज़ीकरण](https://learn.microsoft.com/en-us/dotnet/api/system.threading.semaphoreslim)
- [प्रणाली.Threading.Channels](https://learn.microsoft.com/en-us/dotnet/core/extensions/channels)
- [टीपीएल डाटाफ्लो](https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/dataflow-task-parallel-library)
- [आईएचटीटीपी क्लाइंट फैक्टरी पैटर्न](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests)