Back to "एपमर्मल सिग्नल - अणु को एक सेलिंग नेटवर्क में मोड़ता है"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

Architecture ASP.NET Async Systems Design

एपमर्मल सिग्नल - अणु को एक सेलिंग नेटवर्क में मोड़ता है

Friday, 12 December 2025

एक छोटे से प्राचीन जो मौजूदा में काम करता है एक एडाप्टिव प्रणाली में बदल जाता है।

"क्लासीय सिग्नल पैटर्न"

में पार्ट 1 हमने एननेस्टिकल, निजी, स्वचालन काम के प्रवाह का निर्माण किया. पार्ट 2 हम कि कोऑप्टी पुस्तकालय में बदल दिया, कुंजी के साथ, retrods, और DIt संयोजन के साथ.

यह लेख एक छोटी - सी विशेषता देता है जिसमें सभी परिवर्तन किए जाते हैं: संकेत.

नहीं!

यह अब अल्पपोड में भी है Nuget पैकेज में भी 20 से अधिक से अधिक . Piod पैटर्न और 'stats'.

लागू नहीं लाइसेंस

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

पूरा स्रोत कोड अंदर है अधिकतर अल्पपारदर्शिता

इनमें से सबसे आगे हैं:

IMTA फ़ाइल BAR

------ ---------
एपीड्रॉडिशन. बहुमुखी सिग्नल उत्सर्जन तथा रिज़िक्स से वापसी
एपीटील विकल्प. सिग्नल- निश्चित कॉन्फ़िगरेशन (p)CancelOnSignals, DeferOnSignals, OnSignal, OnSignalRetracted)
स्ट्रिंग इंटरनेशनलमैटर. संकेत फिल्टरिंग के लिए सेल- दर- दर- दर- दर- रंग पैटर्न
सिग्नल अमेरिका.cs Smughuks पैटर्न से मेल खाता हुआ scutता है (c) *, ?, विरामचिह्न सूची, अनुमानीय अनुक्रम)
उदाहरण/ चिह्न एचटीटीपी कॉल के लिए बीजीय नमूना प्लगिन
उदाहरण/ Adrances.s एडाप्टिव दर संकेत- आधारित देरी के साथ समाप्त होता है
उदाहरण/ Ssecs/ SELLICKSBICKS सर्किट ब्रेकर ईनेमर संकेत विंडो शो
उदाहरण/ उदाहरण SITCKS SICKICKS SELANE

समस्या: अणुओं को तहस - नहस कर दिया गया

हमारे पूर्व पूर्वपक समन्वय कार्य में महान हैं, लेकिन वे पृथक कर रहे हैं. हरेक को पता है कि अपने खुद के ऑपरेशन के बारे में, लेकिन क्या प्रणाली में कहीं और हो रहा है के बारे में पता नहीं है.

// Translation coordinator has no idea that...
await translationCoordinator.EnqueueAsync(request);

// ...the API just hit a rate limit
// ...another service is experiencing backpressure
// ...a downstream dependency is slow

हम स्पष्ट निर्भरताओं को जगा सकते हैं, लेकिन यह उत्पन्‍न करता है । एनम्बिएशनमेंट - प्रबंधकों कि सीधे जुड़े बिना उनके वातावरण को समझ सकते हैं.

सिग्नल में अणुओं को उनके पूर्वतम विंडो में छोड़ देते हैं. उन निशानों छोटी घटनाओं की तरह व्यवहार करते हैं:

  • "यह एपीआई सिर्फ दर समाप्त"
  • "इस उपयोक्ता में 3 बार विफल है"
  • "एक भाई या बहन ऑपरेशन अभी भी द्वार पर इंतजार कर रहा है"

Cordiner तब अपना व्यवहार उनके विंडो में दिखाई देने वाले संकेतों पर बदल सकता है. यह बिना निर्भरता के अप्रयोगात्मक जानकारी है.


हल: संचालन पर सिग्नल

से सिग्नल.cs:

public readonly record struct SignalEvent(
    string Signal,
    long OperationId,
    string? Key,
    DateTimeOffset Timestamp,
    SignalPropagation? Propagation = null)
{
    public int Depth => Propagation?.Depth ?? 0;
    public bool WouldCycle(string signal) => Propagation?.Contains(signal) == true;
    public bool Is(string name) => Signal == name;
    public bool StartsWith(string prefix) => Signal.StartsWith(prefix, StringComparison.Ordinal);
}

एक ऑपरेशन के दौरान संकेतों को बढ़ा सकता है ।

यह है, कोई संदेश दलाल. कोई अलग नहीं . सिर्फ ऑपरेशन के लिए संलग्न तार.

क्योंकि संकेत दिखाते हैं कि पूर्वगामी विंडो के अंदर रहते हैं, वे इसकी गारंटी देते हैं: बाध्य आकार, स्वचालित उम्र, और शून्य जीवन - चक्र ।


एपीअल सिग्नल व्यवस्था

व्यवस्था १ - सिग्नल कभी - भी अनियंत्रित ट्रिगर नहीं

एक संकेत, स्वयं से, विनाश का कारण नहीं है । यह केवल पूर्वगामी विंडो में एक तथ्य रिकॉर्ड है. कुछ भी नहीं चलाता क्योंकि एक संकेत दिया गया था.

मूसा की व्यवस्था 2 - पर - ज़बरदस्ती, स्थानीय और वैकल्पिक है

यदि एक अंश एक पर हस्ताक्षरल हैंडलर की परिभाषा देता है, तो यह सर्वसामान्य रूप से चलता है जब एक संकेत निकलता है - लेकिन केवल इसलिए कि कोबाड इसे संलग्न करने के लिए चुना गया. चींटी नहीं जानता कि या परवाह नहीं है. सभी हैंडलरों को मिटाया जाना कोर व्यवहार अचिह्नित करता है.

व्यवस्था 3 - सिग्नल अणु के स्थान हैं

एक संकेत केवल अणु/renter से जुड़ा हुआ है जो उसे उत्पन्न करता है. कोई संकेत या एक और परमाणु नहीं है । वहाँ कोई साझा लिखने योग्य बस नहीं है.

कानून 4 - सिग्नल केवल तथ्य अनदेखा कर रहे हैं

एक संकेत को विशिष्ट करने से अणु के इतिहास में एक तथ्य जोड़ता है । सिग्नल कभी अद्यतन नहीं किया जा सकता या इसपर लिख दिया गया है. क्या आपने कभी इस बारे में बात की है?

कानून 5 - सिग्नल सतह सीमा से कम है और समय सीमित है

सिग्नल केवल कोरी के पूर्व - पूर्व खिड़की के भीतर ही मौजूद है । वे विंडो के बाहर के रूप में स्वचालित समय बीत गया. अगर आप साफ - सफाई में लगे रहें, तो कुछ भी नहीं हो सकता ।

व्यवस्था ६ - दर्शक पढ़ते हैं, वे नहीं लिखते

जब एक क किये गये “क के लिए संकेतों को चेक करता है, यह स्कैन करता है:

इसके विंडो में अणु

और उन अणुओं के लिए भी संकेत दर्शनों में कभी - भी एक परमाणु घटना को नहीं बदला जाता है ।

व्यवस्था ७ - घटना जैसे व्यवहार परत है, कोई प्राधिकृत नहीं

यदि आप फ्लैग को प्लग- आउट कार्य प्रवाहित करना चाहते हैं, तो आपको उपयोग करना होगा:

सिग्नल- जानकारी

एएसईएस- साइनिंगर

और दूसरों को भी।

ये वैकल्पिक परतों हैं जो संकेतों के शीर्ष पर बनायी जाती हैं, उनके सेलेंट नहीं हैं.

कानून 8 - कोई क्रॉस-परेशन नहीं

कोई भी अणु किसी भी तरह का स्नेपशॉट, स्थिति, संकेत, या किसी अन्य परमाणु का मेटाडाटा बदल नहीं सकता । संगठन के माध्यम से होता है:

  • संकेत

  • समझा जा रहा है

  • विंडो

  • पॉलिसी

नहीं लिखा के माध्यम से.

व्यवस्था ९ - विश्‍वव्यापी दृश्य अनियंत्रित हैं, कभी - भी मूँद नहीं

सिग्नल- किनारा या झुंड- आंतरिक सतह संकेतों के साथ मिलकर दृश्‍य दिखा सकते हैं — लेकिन यह हमेशा सिर्फ पढ़ने के लिए, कभी औपचारिक रूप से, कभी लिखने योग्य नहीं है.

नियम १० - हटाना हैंडलर वही कोर तंत्र देता है

यदि सभी हैंडलरों (क्लासल, डाकर्स, प्रक्रियार्स) को अलग कर दिया जाता है, इस व्यवस्था में सही - सही बताया गया है और यह भविष्यवाणी की गयी है । सिग्नल अभी भी अर्थ रखता है क्योंकि वे तथ्य हैं, ट्रिगर नहीं.

सबसे बढ़िया आना - जाना: फुट छपाई, निर्देश नहीं

घटनाएँ फोन कॉल की तरह हैं:

"मैं अभी आपको फोन कर रहा हूँ. ऊपर उठाओ और प्रतिक्रिया करो."

सिग्नल बर्फ में पदचिह्नों की तरह हैं:

"मैं छोड़ दिया कदम. अगर आप जानना चाहते हैं कि मैं कहाँ चला गया - देखो. अगर आप परवाह नहीं है - इसे नज़रअंदाज़. "

यही कारण है कि संकेत कभी ब्रेक, ब्लॉक कभी नहीं, और नियंत्रण प्रवाह के साथ कभी व्यवहार नहीं करते जब तक आप नहीं करते चुनें उन्हें सर्वे करने के लिए।

यह क्या मिटाएँ

फर्क पड़ता है क्योंकि संकेतों को मिटाया जा रहा है:

मुश्‍किलों का सामना करते वक्‍त हमें किन बातों से दूर रहना चाहिए? |---------|:--------------:|:----------------:| लॉएल कोचते हुए प्रचारकों की तारीफ कीजिए, जो कुछ भी नहीं कर पा रहे हैं उरया टिमटिमार्ट एम्बिएंट की प्रतिक्रिया जरूरी एम्बिएंट, एक सर्वे जब तैयार किया जा रहा था [ पेज 9 पर बड़े अक्षरों में लेख की खास बात] अनुमान लगाया गया है कि इस मामले में बहुत - सी बातें शामिल हैं । Libisofs गारंटी देता है/ अनियंत्रित विस्तार योग्य नहीं है, सिर्फ iCalImp INVERDENDDENDEDDENDEDDENDED address [ पेज 13 पर बड़े अक्षरों में लेख की खास बात] [ चित्र का श्रेय]

तेज तुलना

STAssassin विशेषता घटना |---------|--------|---------| हमला करने से पहले उसे पूरा यकीन हो गया था कि वह यहोवा की सेवा करना चाहता है । 20वीं सदी के दौरान हुई घटनाओं पर गौर कीजिए । Azonzancrary/mits, सिर्फ alvervial IMCOS रीफ्रेंस आवश्यक Godome Jogram अतुल्यकालिक डाटा खर्च INVENT भंडार कुछ नहीं बढ़ रहा है LRU- शैली विंडो भक्कील बस्ती की सैर करने के लिए यह बेहद ज़रूरी है कि आप उसे अपनी आँखों से देखने की कोशिश करें । फेल्सिल्स मोड लगभग किसी भी हालत नहीं

कोड में भिन्नता

घटनाएँ निकट हैं (क्लासिक):

public event Action RateLimited;

try
{
    await CallApiAsync();
}
catch (RateLimitException)
{
    RateLimited?.Invoke(); // Makes someone else act right now
}

समस्याएँ:

  • कौन प्रतिक्रिया दिखाता है?
  • किस क्रम में?
  • क्या होगा अगर दो हैंडलर संघर्ष?
  • क्या होगा अगर एक हैंडलर फेंक?
  • क्या होगा अगर यह गलत समय है?
  • क्या होगा अगर कॉलर इस व्यवहार नहीं करना चाहती?

सिग्नल पास (प्रयोगी):

try
{
    await CallApiAsync(ct);
}
catch (RateLimitException ex)
{
    op.Signal($"rate-limit:{ex.RetryAfterMs}ms");
    throw;
}

कुछ भी यहाँ होता है. बाद में, कहीं पूरी तरह से अलग:

if (translator.HasSignal("rate-limit"))
{
    await Task.Delay(1000);   // Act when *we* choose
}

टिप्पणी:

  • कोई प्रत्यक्ष जोड़ नहीं
  • कोई आश्चर्य की बात नहीं
  • कोई चलाने लायक नहीं
  • कोई कालबैक नरक नहीं
  • कोई पार सिंहासन अजीबपन नहीं
  • जब हम कोई प्रतिक्रिया दें पूछें रूप देखने के लिए

"एहह! पंक्ति

घटनाएँ हस्तांतरण नियंत्रण. सिग्नल ट्रांसफर का संदर्भ.

कि एक वाक्य में पूरे मानसिक मॉडल है.

कौन सा सिग्नल वास्तव में हैं

अपनी पृष्ठभूमि पर निर्भर रहना:

ACTCGenericName |----------|------------| | तंत्र वरीयताएँComment अगर आप चाहते हैं कि आपका बच्चा आपकी मेहनत पर ध्यान दे, तो आप क्या कर सकते हैं? | इंजिन कच्चे विंडो को बाध्य किये जाने वाले ऑपरेशनों में संलग्न हल्के प्रकाश मेटाडाटा | PL/ CLCKrs वह कहती है: “जब मुझे पता चला कि मैं एक डॉक्टर से बात कर रहा हूँ, तो मुझे लगा कि वह मुझसे बात कर रहा है । | फ्रेमवर्क उपयोक्ता सेंटीमीटर एक इन प्रक्रिया, स्व- सफाई स्थिति आप किसी भी समय पर प्रश्न कर सकते हैं

कोई भी व्यक्‍ति प्रतिक्रिया दिखाने के लिए बाध्य नहीं है । एसिगिगरिकusa. kgm एक ही चींटियों का मॉडल इस्तेमाल करता है, वही अश्‍वेत व्यवस्थाएँ जो सन्‌ एआई में प्रयोग की जाती हैं, और वही आधुनिक अपराधिक नेटवर्क संकेतों पर संकेत देती हैं ।


अन्य प्रश्‍नों से यह कैसे तुलना करता है

समझ - बूझ से काम लेना / खोलना

using var activity = source.StartActivity("ProcessOrder");
activity?.SetTag("order.id", orderId);
activity?.SetTag("rate.limited", true);

के लिए उत्तम: सेवा सेवा के दौरान, लंबी-टर्मेज भंडार, कोरी आईडी.

जब चेक किया जाए तो श्रेणी का प्रयोग करें: आपको अनेक सेवाओं के पार अनुरोधों का पता लगाने की जरूरत है, विश्लेषण के लिए मेरे सुझावों को जमा करना, या निगरानी औज़ारों के साथ एकीकृत.

जब एपेक्ट्डल संकेत इस्तेमाल करें तो इस्तेमाल करें: आप एक तंत्रिकापन, प्रतिक्रियापूर्ण अनुकूल अनुकूलता की जरूरत है, या नहीं करना चाहते हैं .

प्रक्रिया विस्तार (आरx)

var rateLimits = Observable.FromEventPattern<RateLimitEventArgs>(
    h => api.RateLimitHit += h,
    h => api.RateLimitHit -= h);

rateLimits
    .Throttle(TimeSpan.FromSeconds(1))
    .Subscribe(e => HandleRateLimit(e));

के लिए उत्तम: जटिल घटना प्रक्रिया, समय- आधारित ऑपरेशन, विविध घटनाओं के चिह्न.

जब आरएक्स इस्तेमाल करें: आपको जटिल जगहों की ज़रूरत होती है (बहुत ज़्यादा शराब पीना, गलत काम करना, अलग - अलग नदियों की ज़रूरत है) ।

जब एपेक्ट्डल संकेत इस्तेमाल करें तो इस्तेमाल करें: आप सरल एप्पिंग, स्वचालित साफ सफाई, या संचालन ट्रैक के साथ एकीकरण करना चाहते हैं.

मीडियाटीआर सूचनाएँ

public class RateLimitNotification : INotification
{
    public int RetryAfterMs { get; init; }
}

await _mediator.Publish(new RateLimitNotification { RetryAfterMs = 5000 });

के लिए उत्तम: बहुत से हैंडलरों के साथ हैंडल की गई प्रक्रिया की घटना.

मीडिया- आर इस्तेमाल करें जब: आप एक ही घटना के प्रति प्रतिक्रिया दिखाने के लिए बहुत से हैंडलर चाहते हैं.

जब एपेक्ट्डल संकेत इस्तेमाल करें तो इस्तेमाल करें: आप प्रत्यक्ष सब्सक्रिप्शन, स्वयं को साफ़ करने के इतिहास, या एकीकरण चाहते हैं.

पोलाइल सर्किट ब्रेकर

var circuitBreaker = Policy
    .Handle<HttpRequestException>()
    .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));

के लिए उत्तम: व्यक्‍तिगत कॉल के साथ एक व्यक्‍तिगत कॉल के साथ सहवास ।

जब पोल इस्तेमाल करें: आपको प्रति-फोन की आवश्यकता है स्वचालित आधा खोलने/ संलग्न संक्रमण के साथ.

जब एपेक्ट्डल संकेत इस्तेमाल करें तो इस्तेमाल करें: आप कई ऑपरेशनों, मनपसंद सर्किट तर्क, या ऑपरेशन के साथ एकीकरण के बारे में सचेत होना चाहते हैं ।

उन्हें सम्मिलित करें: जब सर्किट दौरे होता है, तो अलग - अलग संकेतों का इस्तेमाल कीजिए ।

तुलना तालिका

DARANTAN_BAR_ स्वयं को साफ़ करने वाला ADLLLANDL DCALLLLLLLICKL मनपसंद तर्क DCONELELLLLLAN_BAR_BAR_ |----------|:-------------:|:---------------:|:---------:|:------------:|:-----------:| Git ओपन- लैम्प्गा BAR GiB से होकर बाहरी औजार का विश्लेषण करे एलआईएम विस्तार विस्तार विस्तार विस्तार मिना मीडिया आरएसटी खाकरार खुशखबरी का प्रचार करता है (एमईएसएम) लिखा (एमईएमईएमआई) लिखा है जो उन लोगों की मदद करता है जो सिर्फ अपने देश में रहते हैं सन 2002- 2002 सर्किट ब्रेकर © 2002- 2002 | एपीटर्म सिग्नल घड़ू आदमियों की देखभाल करने के लिए इससे पहले कि उन दोनों ने कोई अर्ज़ी भरी हो तो हम दोनों ने उसे पूरी तरह से माफ कर दिया ।


माता - पिताओं को अपने बच्चों की परवरिश करने के लिए क्या करना चाहिए?

संचालन संचालन संचालन ISignalEmitter:

public interface ISignalEmitter
{
    // Emit signals
    void Emit(string signal);
    bool EmitCaused(string signal, SignalPropagation? cause);

    // Retract (remove) signals
    bool Retract(string signal);
    int RetractMatching(string pattern);
    bool HasSignal(string signal);

    long OperationId { get; }
    string? Key { get; }
}

अपने काम के शरीर के अंदर:

await coordinator.ProcessAsync(async (item, op, ct) =>
{
    try
    {
        var result = await CallExternalApiAsync(item, ct);

        if (result.WasCached)
            op.Signal("cache-hit");

        if (result.Duration > TimeSpan.FromSeconds(2))
            op.Signal("slow-response");
    }
    catch (RateLimitException ex)
    {
        op.Signal("rate-limit");
        op.Signal($"rate-limit:{ex.RetryAfterMs}ms");
        throw;
    }
    catch (TimeoutException)
    {
        op.Signal("timeout");
        throw;
    }
});

सिग्नल सिर्फ स्ट्रिंग हैं. सरल नाम इस्तेमाल करें (y)"rate-limit"(स्फीयर्ड नामों) या संरचनात्मक नाम ()"rate-limit:5000ms"). पैटर्न फ़िल्टर ब्लॉबिक्स का प्रयोग करें (x)*, ?(c) तथा समर्थन कॉम्स्क सूची ()"error.*,timeout". जोड़ता है ज्ञानात्मक और आवंटन के माध्यम से StringPatternMatcher.

बढ़िया-GEREAped सिग्नल उदाहरण: HTTP कॉल

बहुत विस्तृत ब्लॉइडीमेंट के लिए, आप ऑपरेशन के प्रत्येक चरण में संकेत निकाल सकते हैं. लाइब्रेरी में नमूना भी शामिल है सिग्नलीकरण_BAR_ जो इस पैटर्न को दिखाता है:

using Mostlylucid.Helpers.Ephemeral.Examples;

// Inside your work body where you have access to the operation's emitter:
await coordinator.ProcessAsync(async (request, op, ct) =>
{
    var data = await SignalingHttpClient.DownloadWithSignalsAsync(
        httpClient,
        new HttpRequestMessage(HttpMethod.Get, request.Url),
        op,  // ISignalEmitter
        ct);

    // Process the downloaded data...
});

यह प्रत्येक स्टेज पर संकेत करती है

STACKS सिग्नल जब 2004 |--------|------| | stage.starting निवेदन शुरू होने से पहले खाली स्थान | progress:0 %s आरंभिक प्रगति चिह्न | stage.request SIN HTTP आग्रह | stage.headers SpamAssassin अनुक्रिया शीर्षिका पाया गया | stage.reading SpamAssassin बॉडी को पढ़ने के लिए प्रारंभ किया जा रहा है | progress:XX डाउनलोड विंडो की प्रगति प्रतिशत (0.- 100) | stage.completed डाउनलोड समाप्त

आप फिर इन चेक पैटर्न मेल के साथ क्वैरी कर सकते हैं:

// Find all stage transitions
var stages = coordinator.GetSignalsByPattern("stage.*");

// Check download progress
var progress = coordinator.GetSignalsByPattern("progress:*");

// Check if any download is still in progress
if (coordinator.HasSignalMatching("stage.reading") &&
    !coordinator.HasSignalMatching("stage.completed"))
{
    // Download in progress
}

सिग्नल फिर से चालू किया जा रहा है

संचालन उनके स्वयं के संकेतों को हटा सकता है. यह अस्थायी राज्यों के लिए उपयोगी है:

await coordinator.ProcessAsync(async (item, op, ct) =>
{
    // Mark as processing
    op.Emit("processing");

    try
    {
        await ProcessItemAsync(item, ct);

        // Success - retract the processing signal
        op.Retract("processing");
        op.Emit("completed");
    }
    catch (RetryableException)
    {
        // Keep processing signal, add retry info
        op.Emit("retrying");
    }
    catch (Exception)
    {
        // Remove all temporary signals
        op.RetractMatching("processing*");
        op.Emit("failed");
        throw;
    }
});

घटना फिर से प्रारंभ किया जा रहा है

बस संकेत उत्सर्जन की तरह, वापसी कॉल चालू कर सकते हैं:

var coordinator = new EphemeralWorkCoordinator<Request>(
    body,
    new EphemeralOptions
    {
        // Sync retraction handler
        OnSignalRetracted = evt =>
        {
            _metrics.DecrementGauge(evt.Signal);
            Console.WriteLine($"Signal {evt.Signal} retracted from op {evt.OperationId}");

            if (evt.WasPatternMatch)
                Console.WriteLine($"  (matched pattern: {evt.Pattern})");
        },

        // Async retraction handler
        OnSignalRetractedAsync = async (evt, ct) =>
        {
            await _telemetry.TrackRetraction(evt.Signal, evt.OperationId, ct);
        }
    });

वह SignalRetractedEvent इसमें:

  • Signal - वापस संकेत नाम
  • OperationId - यह वापस किया कि ऑपरेशन
  • Key - ऑपरेशन की कुंजी (यदि कोई हो)
  • Timestamp - जब वापसी हो
  • WasPatternMatch - सही अगर इसके द्वारा वापस किया गया है RetractMatching
  • Pattern - पैटर्न उपयोग किया (यदि पैटर्न प्रतियोगिता)

वास्तविक विश्वव्यापी उदाहरण: दर सीमा

await coordinator.ProcessAsync(async (request, op, ct) =>
{
    // Check if we already have a rate limit signal
    if (op.HasSignal("rate-limited"))
    {
        // We're in recovery mode
        await Task.Delay(1000, ct);
    }

    try
    {
        var response = await _api.SendAsync(request, ct);

        // Success! Remove any rate limit signal
        if (op.Retract("rate-limited"))
        {
            op.Emit("rate-limit-cleared");
        }
    }
    catch (RateLimitException ex)
    {
        op.Emit("rate-limited");
        op.Emit($"rate-limit:{ex.RetryAfterMs}ms");
        throw;
    }
});

सेंसिंग सिग्नल

सभी समन्वयित सिग्नल क्वैरी प्रदान करते हैं:

// Check if any recent operation hit a rate limit
if (coordinator.HasSignal("rate-limit"))
{
    await Task.Delay(1000);
}

// Count slow responses in the window
var slowCount = coordinator.CountSignals("slow-response");
if (slowCount > 10)
{
    await ThrottleAsync();
}

// Get signals by pattern
var httpErrors = coordinator.GetSignalsByPattern("http.error.*");

// Get signals since a time
var recentSignals = coordinator.GetSignalsSince(DateTimeOffset.UtcNow.AddMinutes(-1));

// Get signals for a specific key
var userSignals = coordinator.GetSignalsByKey("user-123");

सिग्नल-पुष्टि प्रक्रिया

से एपीटील विकल्प.:

कोऑपरेटर संकेतों पर स्वतः प्रतिक्रिया दिखा सकते हैं:

var coordinator = new EphemeralWorkCoordinator<Request>(
    body,
    new EphemeralOptions
    {
        // Cancel new work if these signals are present
        CancelOnSignals = new HashSet<string> { "system-overload", "circuit-open" },

        // Defer new work while these signals are present
        DeferOnSignals = new HashSet<string> { "rate-limit" },
        MaxDeferAttempts = 10,
        DeferCheckInterval = TimeSpan.FromMilliseconds(100)
    });

जब एक संकेत आए CancelOnSignals पता लगा लिया गया है, नई वस्तुओं को छोड़ा गया है (जैसे संख्या गुम हो गई है). जब एक संकेत आए DeferOnSignals पता चला है, नए मद इंतजार करें जब तक संकेत स्पष्ट नहीं हो जाता.


वास्तविक विश्वव्यापी उदाहरण: एडाप्टिव दर सीमा

से एडाप्टिवीकरण सर्विस.:

public class AdaptiveTranslationService : IAsyncDisposable
{
    private readonly EphemeralWorkCoordinator<TranslationRequest> _coordinator;
    private readonly ITranslationApi _translationApi;

    public AdaptiveTranslationService(ITranslationApi translationApi)
    {
        _translationApi = translationApi;

        _coordinator = new EphemeralWorkCoordinator<TranslationRequest>(
            ProcessTranslationAsync,
            new EphemeralOptions
            {
                MaxConcurrency = 8,
                MaxTrackedOperations = 100,

                // New work is deferred while any "rate-limit" or "rate-limit:*" signal is present
                DeferOnSignals = new HashSet<string> { "rate-limit", "rate-limit:*" },
                MaxDeferAttempts = 10,
                DeferCheckInterval = TimeSpan.FromMilliseconds(100)
            });
    }

    public async Task TranslateAsync(TranslationRequest request)
    {
        // Optional: extra politeness based on most recent retry-after
        var rateLimitSignals = _coordinator.GetSignalsByPattern("rate-limit:*");
        if (rateLimitSignals.Count > 0)
        {
            var latest = rateLimitSignals
                .OrderByDescending(s => s.Timestamp)
                .First()
                .Signal; // "rate-limit:5000ms"

            if (TryParseRetryAfter(latest, out var delay))
            {
                await Task.Delay(delay);
            }
        }

        await _coordinator.EnqueueAsync(request);
    }

    public static bool TryParseRetryAfter(string signal, out TimeSpan delay)
    {
        delay = default;
        var parts = signal.Split(':', 2);
        if (parts.Length != 2) return false;

        var payload = parts[1].Trim();
        if (!payload.EndsWith("ms", StringComparison.OrdinalIgnoreCase)) return false;

        var numPart = payload[..^2];
        if (!int.TryParse(numPart, out var ms) || ms < 0) return false;

        delay = TimeSpan.FromMilliseconds(ms);
        return true;
    }
}

जब दर सीमा हिट की जाती है तो इस सेवा का प्रत्येक उदाहरण स्वचालित रूप से पीछे हटाया जाता है. कोई साझा नहीं है. सिर्फ र्निक विंडो पढ़ा जा रहा है.


वास्तविक विश्वव्यापी उदाहरण: क्रॉस- कोरिएटर

बहु संयोजक एक साझा के माध्यम से एक दूसरे को समझ सकते हैं SignalSink:

public class OrderProcessingSystem
{
    private readonly SignalSink _sharedSignals = new(maxCapacity: 1000);

    private readonly EphemeralWorkCoordinator<Order> _orderProcessor;
    private readonly EphemeralWorkCoordinator<PaymentRequest> _paymentProcessor;

    public OrderProcessingSystem()
    {
        var options = new EphemeralOptions { Signals = _sharedSignals };

        _orderProcessor = new EphemeralWorkCoordinator<Order>(
            ProcessOrderAsync, options);

        _paymentProcessor = new EphemeralWorkCoordinator<PaymentRequest>(
            ProcessPaymentAsync, options);
    }

    public async Task ProcessOrderAsync(Order order)
    {
        // Check shared signals for payment gateway issues
        if (_sharedSignals.Detect("gateway-error"))
        {
            await _retryQueue.EnqueueAsync(order);
            return;
        }

        await _orderProcessor.EnqueueAsync(order);
    }
}

वास्तविक विश्व उदाहरण: स्वास्थ्य मॉनीटर

[HttpGet("/health/detailed")]
public IActionResult GetDetailedHealth()
{
    return Ok(new
    {
        translation = new
        {
            pending = _translationCoordinator.PendingCount,
            active = _translationCoordinator.ActiveCount,
            recentRateLimits = _translationCoordinator.CountSignals("rate-limit"),
            recentTimeouts = _translationCoordinator.CountSignals("timeout"),
            recentSuccess = _translationCoordinator.CountSignals("success"),
            hasErrors = _translationCoordinator.HasSignalMatching("error.*")
        },
        payment = new
        {
            pending = _paymentCoordinator.PendingCount,
            gatewayErrors = _paymentCoordinator.CountSignals("gateway-error"),
            declines = _paymentCoordinator.CountSignals("declined"),
            approvals = _paymentCoordinator.CountSignals("approved")
        }
    });
}

कोई मीडिया लाइब्रेरी की ज़रूरत नहीं है. सिर्फ एपलाइडल विंडो को क्वैरी करें.


वास्तविक विश्वव्यापी उदाहरण: सिग्नल-आधार सर्किट ब्रेकिंग

से सिग्नल बेसेइड- ऑपरेशनर.:

public class SignalBasedCircuitBreaker
{
    private readonly string _failureSignal;
    private readonly int _threshold;
    private readonly TimeSpan _windowSize;

    public SignalBasedCircuitBreaker(
        string failureSignal = "failure",
        int threshold = 5,
        TimeSpan? windowSize = null)
    {
        _failureSignal = failureSignal;
        _threshold = threshold;
        _windowSize = windowSize ?? TimeSpan.FromSeconds(30);
    }

    public bool IsOpen<T>(EphemeralWorkCoordinator<T> coordinator)
    {
        var recentFailures = coordinator.GetSignalsSince(
            DateTimeOffset.UtcNow - _windowSize);

        return recentFailures.Count(s => s.Signal == _failureSignal) >= _threshold;
    }

    public int GetFailureCount<T>(EphemeralWorkCoordinator<T> coordinator)
    {
        var recentFailures = coordinator.GetSignalsSince(
            DateTimeOffset.UtcNow - _windowSize);

        return recentFailures.Count(s => s.Signal == _failureSignal);
    }
}

// Usage
var circuitBreaker = new SignalBasedCircuitBreaker("api-error", threshold: 3);

if (circuitBreaker.IsOpen(_coordinator))
{
    throw new CircuitOpenException("Too many recent API errors");
}

await _coordinator.EnqueueAsync(request);

सर्किट ब्रेकर के पास अपने - आप की कोई स्थिति नहीं है ।


सिग्नल: असीमित लूप्स को रोकें

से सिग्नल.cs:

संकेत अन्य संकेतों का कारण हो सकता है, आप अनंत लूप का जोखिम. SignalConstraints इस में रोक रखें:

var options = new EphemeralOptions
{
    SignalConstraints = new SignalConstraints
    {
        // Max propagation depth before blocking
        MaxDepth = 10,

        // Prevent A → B → A cycles
        BlockCycles = true,

        // Signals that end propagation chains
        TerminalSignals = new HashSet<string> { "completed", "failed", "resolved" },

        // Signals that emit but don't propagate
        LeafSignals = new HashSet<string> { "logged", "metric" },

        // Callback when a signal is blocked
        OnBlocked = (signal, reason) =>
        {
            _logger.LogWarning("Signal {Signal} blocked: {Reason}",
                signal.Signal, reason);
        }
    }
};

सिग्नल प्रोग्रेसिव

अनुकूलता के साथ ट्रैक करें EmitCaused:

public void HandleSignal(SignalEvent evt, ISignalEmitter emitter)
{
    if (evt.Is("order-placed"))
    {
        // This signal carries the propagation chain
        // Will be blocked if it would create a cycle
        emitter.EmitCaused("inventory-reserved", evt.Propagation);
    }
}

विस्फोटित चैन पथ: order-placed → inventory-reserved → ...

यदि inventory-reserved बनाने की कोशिश की गई order-placedइसे रोका जाएगा।


सिग्नल- स्याही: वैश्विक सिग्नल जगह

से सिग्नल.cs:

संकेतों के लिए जिसे कोऑप्टी के पार दिखाई जानी चाहिए:

public sealed class SignalSink
{
    private readonly ConcurrentQueue<SignalEvent> _window;
    private readonly int _maxCapacity;
    private readonly TimeSpan _maxAge;

    public SignalSink(int maxCapacity = 1000, TimeSpan? maxAge = null);

    // Raise signals
    public void Raise(SignalEvent signal);
    public void Raise(string signal, string? key = null);

    // Sense signals
    public IReadOnlyList<SignalEvent> Sense();
    public IReadOnlyList<SignalEvent> Sense(Func<SignalEvent, bool> predicate);
    public bool Detect(string signalName);
    public bool Detect(Func<SignalEvent, bool> predicate);

    public int Count { get; }
}

उपयोग:

// Create a shared sink
var sink = new SignalSink(maxCapacity: 1000, maxAge: TimeSpan.FromMinutes(2));

// Configure coordinators to use it
var options = new EphemeralOptions { Signals = sink };

// Or raise signals directly
sink.Raise("system-maintenance");

// Sense from anywhere
if (sink.Detect("system-maintenance"))
{
    await DeferWorkAsync();
}

स्ट्रिंग इंटरेक्शनर के साथ मेल खाता पैटर्न

से स्ट्रिंग इंटरनेशनलमैटर.:

संकेत फ़िल्टरिंग के लिए ग्लोब- शैली

// Exact match
coordinator.HasSignal("rate-limit");

// Wildcard patterns
coordinator.HasSignalMatching("http.*");           // http.timeout, http.error
coordinator.HasSignalMatching("error.*.critical"); // error.payment.critical
coordinator.HasSignalMatching("user-???-failed");  // user-123-failed

// Comma-separated patterns in CancelOnSignals/DeferOnSignals
new EphemeralOptions
{
    CancelOnSignals = new HashSet<string>
    {
        "system-overload, circuit-open",  // Either pattern
        "error.*"                          // Any error signal
    }
}

सिग्नल नामी अधिवेशन

संकेतों को सादा रखें और जारी रखें:

// Good - simple, categorical
op.Signal("success");
op.Signal("failure");
op.Signal("rate-limit");
op.Signal("timeout");
op.Signal("cache-hit");

// Good - structured for parsing
op.Signal("rate-limit:5000ms");
op.Signal("retry:attempt-3");
op.Signal("slow:2500ms");
op.Signal("http.error:429");

// Good - hierarchical for pattern matching
op.Signal("payment.declined");
op.Signal("payment.approved");
op.Signal("payment.gateway-error");

// Avoid - entity identification belongs in Key, not signals
op.Signal("user-123-rate-limited");  // Bad

// Instead
op.Key = "user-123";
op.Signal("rate-limit");

एसईएस सिग्नल हैंडलिंग

Sytcial सिग्नल हैंडलर्स (संपारिवारिक रूप से)OnSignal) ऑपरेशन के थ्रेड पर चलाने के लिए, उन्हें तेजी से बनाए रखें. मैं/O-O-Mod काम करने के लिए, प्रशंसकों को एक अतुल्यकालिक पथ में लाने के लिए SignalDispatcher ( पैटर्न जोड़ता है, गणनाात्मक अनुक्रम) AsyncSignalProcessor.

सिग्नल- सेन्सर प्रशंसक

await using var dispatcher = new SignalDispatcher(new EphemeralOptions
{
    MaxConcurrency = Environment.ProcessorCount,
    MaxConcurrencyPerKey = 1  // sequential per signal name by default
});

dispatcher.Register("error.*", evt => _alerts.SendAsync(evt.Signal));
dispatcher.Register("progress:*", evt => _metrics.Record(evt.Signal));

// In coordinator options, keep OnSignal chor options, keep OnSignal cheap and enqueue
var coordinator = new EphemeralWorkCoordinator<Request>(
    body,
    new EphemeralOptions
    {
        OnSignal = dispatcher.Dispatch
    });

पैटर्न समर्थन *, ?, तथा विरामचिह्न सूची (S)"error.*,timeout". सभी मिलान हैंडलरों को रजिस्टर करने के क्रम में चलाने के लिए एक पृष्ठभूमि के कवर्ड कवर्ड कोष है.

एएसईएस- साइनिंगर

स्टैंडअलोन ब्रेक प्रक्रिया के लिए:

await using var processor = new AsyncSignalProcessor(
    async (signal, ct) =>
    {
        await _externalService.LogAsync(signal, ct);
    },
    maxConcurrency: 4,
    maxQueueSize: 1000);

// Enqueue signals (returns immediately)
processor.Enqueue(new SignalEvent(
    "rate-limit",
    operationId,
    key,
    DateTimeOffset.UtcNow));

टेमर्मसरर उदाहरण

एक पूर्ण उदाहरण

स्रोत: टेर्मर्मर्मर.

public class TelemetrySignalHandler : IAsyncDisposable
{
    private readonly AsyncSignalProcessor _processor;
    private readonly ITelemetryClient _telemetry;

    public TelemetrySignalHandler(ITelemetryClient telemetry)
    {
        _telemetry = telemetry;
        _processor = new AsyncSignalProcessor(
            HandleSignalAsync,
            maxConcurrency: 8,
            maxQueueSize: 5000);
    }

    // Synchronous entry point - returns immediately
    public bool OnSignal(SignalEvent signal) => _processor.Enqueue(signal);

    private async Task HandleSignalAsync(SignalEvent signal, CancellationToken ct)
    {
        var properties = new Dictionary<string, string>
        {
            ["signal"] = signal.Signal,
            ["operationId"] = signal.OperationId.ToString(),
            ["key"] = signal.Key ?? "none"
        };

        await _telemetry.TrackEventAsync("EphemeralSignal", properties, ct);

        // Categorized tracking based on signal prefix
        if (signal.StartsWith("error"))
            await _telemetry.TrackExceptionAsync(signal.Signal, properties, ct);
        else if (signal.StartsWith("perf"))
            await _telemetry.TrackMetricAsync(signal.Signal, 1, ct);
    }

    // Expose stats for monitoring
    public int QueuedCount => _processor.QueuedCount;
    public long ProcessedCount => _processor.ProcessedCount;
    public long DroppedCount => _processor.DroppedCount;

    public async ValueTask DisposeAsync() => await _processor.DisposeAsync();
}

इसे अपने कर्ड में तार:

await using var telemetryHandler = new TelemetrySignalHandler(telemetryClient);

await using var coordinator = new EphemeralWorkCoordinator<Request>(
    ProcessAsync,
    new EphemeralOptions
    {
        OnSignal = signal => telemetryHandler.OnSignal(signal)
    });

हैंडलर:

  • कभी ब्लॉक नहीं ऑपरेशन थ्रेड - OnSignal तुरंत लौटाता है
  • श्रेणियां भिन्न प्रकार के लिए उपसर्ग द्वारा
  • वायरस का सामना करना (कांट, प्रोसेस, छोड़ा) स्वास्थ्य की देख - भाल करने के लिए
  • सीमाएँ स्मरण - सबसे पुराना संकेत यदि क़तार में भर जाता है

यह क्यों कार्य करता है

सिग्नल शक्तिशाली हैं क्योंकि वे कर रहे हैं एपेर्निकusa. kgm:

आपसी रिश्‍तों के बारे में आपका क्या खयाल है? |----------|---------| | बाउंड्ड ऑस्कर बड़ी उम्र के संकेत बाहर नहीं बढ़ सकते | अपने आप को शुद्ध कर रहा है arbfp में कोई साफ कोड जरूरी नहीं | डकोल्डल्ड Merverster श्रोताों के बारे में पता नहीं है | ऑबॉबेबल तत्व का कोई भी कोड मौजूदा स्टेट तत्व को सूचित कर सकता है | निजी STAssassin कोई उपयोक्ता आंकड़ा नहीं - सिर्फ सिग्नल नाम | तेज IMTACO( 1) संक्षिप्त- अनुग्रह सहित जाँच करता है

एरिफ़ल विंडो पहले से ही उपयोग में है डिबगिंग के लिए. सिग्नल सिर्फ यह दे देता है.


कंटेनमेंट

सिग्नल अलग होने वाले अणुओं को एक में बदल देता है नेटवर्क को समझा जा रहा है. हरर्ड कर सकते हैं:

  • एमआईटी संकेत कि यह क्या अनुभव किया के बारे में संकेत
  • सचेत करता है अपने इतिहास से संकेत या साझेदारी सिंक से संकेत
  • फिर से कोशिश करें स्वचालित के द्वारा CancelOnSignals और DeferOnSignals

कोई संदेश स्लॉट नहीं. कोई साझेदारी स्थिति नहीं. मेटाडेटा की सामग्री के साथ कार्य करें जो कि स्वाभाविक रूप से सड़ता है.

परमाणु सीधे एक दूसरे से बात नहीं करते हैं - वे सिर्फ एनपीरल विंडो में निशान छोड़ देते हैं कि अन्य लोग देख सकते हैं।

आग ... सिग्नल ... होश में... भूल जाओ.


लिंक्स

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.