[{"data":1,"prerenderedAt":713},["ShallowReactive",2],{"navigation":3,"\u002Flocks\u002Fmutex":151,"\u002Flocks\u002Fmutex-surround":708},[4,29,56,79,94,121,128,144],{"title":5,"path":6,"stem":7,"children":8,"icon":27,"defaultOpen":28},"Getting Started","\u002Fgetting-started","1.getting-started\u002F1.index",[9,12,17,22],{"title":10,"path":6,"stem":7,"icon":11},"Introduction","i-lucide-book-open",{"title":13,"path":14,"stem":15,"icon":16},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"Redis setup","\u002Fgetting-started\u002Fredis-setup","1.getting-started\u002F3.redis-setup","i-lucide-database",{"title":23,"path":24,"stem":25,"icon":26},"Quickstart","\u002Fgetting-started\u002Fquickstart","1.getting-started\u002F4.quickstart","i-lucide-zap","i-lucide-rocket",true,{"title":30,"icon":31,"path":32,"stem":33,"children":34,"page":55},"Concepts","i-lucide-lightbulb","\u002Fconcepts","2.concepts",[35,40,45,50],{"title":36,"path":37,"stem":38,"icon":39},"Keys","\u002Fconcepts\u002Fkeys","2.concepts\u002F1.keys","i-lucide-key-round",{"title":41,"path":42,"stem":43,"icon":44},"Strict vs lax","\u002Fconcepts\u002Fstrict-vs-lax","2.concepts\u002F2.strict-vs-lax","i-lucide-scale",{"title":46,"path":47,"stem":48,"icon":49},"Comparators","\u002Fconcepts\u002Fcomparators","2.concepts\u002F3.comparators","i-lucide-git-compare",{"title":51,"path":52,"stem":53,"icon":54},"Errors","\u002Fconcepts\u002Ferrors","2.concepts\u002F4.errors","i-lucide-triangle-alert",false,{"title":57,"path":58,"stem":59,"children":60,"icon":63},"Counters","\u002Fcounters","3.counters\u002F1.index",[61,64,69,74],{"title":62,"path":58,"stem":59,"icon":63},"Overview","i-lucide-hash",{"title":65,"path":66,"stem":67,"icon":68},"StrictCounter","\u002Fcounters\u002Fstrict-counter","3.counters\u002F2.strict-counter","i-lucide-target",{"title":70,"path":71,"stem":72,"icon":73},"LaxCounter","\u002Fcounters\u002Flax-counter","3.counters\u002F3.lax-counter","i-lucide-wind",{"title":75,"path":76,"stem":77,"icon":78},"Conditional & batch operations","\u002Fcounters\u002Fconditional-and-batch","3.counters\u002F4.conditional-and-batch","i-lucide-layers",{"title":80,"path":81,"stem":82,"children":83,"icon":85},"Instance-aware counters","\u002Finstance-aware-counters","4.instance-aware-counters\u002F1.index",[84,86,90],{"title":62,"path":81,"stem":82,"icon":85},"i-lucide-network",{"title":87,"path":88,"stem":89,"icon":68},"StrictInstanceAwareCounter","\u002Finstance-aware-counters\u002Fstrict","4.instance-aware-counters\u002F2.strict",{"title":91,"path":92,"stem":93,"icon":73},"LaxInstanceAwareCounter","\u002Finstance-aware-counters\u002Flax","4.instance-aware-counters\u002F3.lax",{"title":95,"path":96,"stem":97,"children":98,"icon":100},"Locks","\u002Flocks","5.locks\u002F1.index",[99,101,106,111,116],{"title":62,"path":96,"stem":97,"icon":100},"i-lucide-lock",{"title":102,"path":103,"stem":104,"icon":105},"Mutex","\u002Flocks\u002Fmutex","5.locks\u002F2.mutex","i-lucide-lock-keyhole",{"title":107,"path":108,"stem":109,"icon":110},"RwLock","\u002Flocks\u002Frwlock","5.locks\u002F3.rwlock","i-lucide-book-lock",{"title":112,"path":113,"stem":114,"icon":115},"Lock options","\u002Flocks\u002Foptions","5.locks\u002F4.options","i-lucide-sliders-horizontal",{"title":117,"path":118,"stem":119,"icon":120},"Guard state & errors","\u002Flocks\u002Fguard-state","5.locks\u002F5.guard-state","i-lucide-shield-alert",{"title":122,"path":123,"stem":124,"children":125,"icon":127},"Rate limiting","\u002Frate-limiting","6.rate-limiting\u002F1.index",[126],{"title":122,"path":123,"stem":124,"icon":127},"i-lucide-gauge",{"title":129,"icon":130,"path":131,"stem":132,"children":133,"page":55},"Reference","i-lucide-book-marked","\u002Freference","7.reference",[134,139],{"title":135,"path":136,"stem":137,"icon":138},"Feature flags","\u002Freference\u002Ffeature-flags","7.reference\u002F1.feature-flags","i-lucide-flag",{"title":140,"path":141,"stem":142,"icon":143},"API reference","\u002Freference\u002Fapi","7.reference\u002F2.api","i-lucide-file-code",{"title":145,"path":146,"stem":147,"children":148,"icon":150},"Changelog","\u002Fchangelog","8.changelog\u002F1.index",[149],{"title":145,"path":146,"stem":147,"icon":150},"i-lucide-scroll",{"id":152,"title":102,"badge":153,"body":154,"date":153,"description":702,"extension":703,"links":153,"meta":704,"navigation":705,"path":103,"seo":706,"stem":104,"__hash__":707},"docs\u002F5.locks\u002F2.mutex.md",null,{"type":155,"value":156,"toc":696},"minimark",[157,168,173,323,332,336,509,513,516,574,590,594,600,692],[158,159,160,163,164,167],"p",{},[161,162,102],"code",{}," gives at most one holder across all processes sharing the same Redis key. It mirrors ",[161,165,166],{},"tokio::sync::Mutex",", minus the inner data - the guard is purely a token that says \"you hold the lock\".",[169,170,172],"h2",{"id":171},"construct","Construct",[174,175,180],"pre",{"className":176,"code":177,"language":178,"meta":179,"style":179},"language-rust shiki shiki-themes material-theme-lighter github-light github-dark","use distkit::{DistkitRedisKey, lock::{Mutex, LockOptions}};\n\nlet key = DistkitRedisKey::try_from(\"invoice_42\".to_string())?;\nlet mutex = Mutex::new(LockOptions::new(key, conn));\n","rust","",[161,181,182,226,232,283],{"__ignoreMap":179},[183,184,187,191,195,199,203,206,209,212,214,216,218,220,223],"span",{"class":185,"line":186},"line",1,[183,188,190],{"class":189},"sw1J6","use",[183,192,194],{"class":193},"sbgvK"," distkit",[183,196,198],{"class":197},"smGrS","::",[183,200,202],{"class":201},"sP7_E","{",[183,204,205],{"class":193},"DistkitRedisKey",[183,207,208],{"class":201},",",[183,210,211],{"class":193}," lock",[183,213,198],{"class":197},[183,215,202],{"class":201},[183,217,102],{"class":193},[183,219,208],{"class":201},[183,221,222],{"class":193}," LockOptions",[183,224,225],{"class":201},"}};\n",[183,227,229],{"class":185,"line":228},2,[183,230,231],{"emptyLinePlaceholder":28},"\n",[183,233,235,239,243,246,249,251,255,258,262,266,268,271,274,277,280],{"class":185,"line":234},3,[183,236,238],{"class":237},"sbsja","let",[183,240,242],{"class":241},"su5hD"," key ",[183,244,245],{"class":197},"=",[183,247,248],{"class":193}," DistkitRedisKey",[183,250,198],{"class":197},[183,252,254],{"class":253},"sGLFI","try_from",[183,256,257],{"class":201},"(",[183,259,261],{"class":260},"sjJ54","\"",[183,263,265],{"class":264},"s_sjI","invoice_42",[183,267,261],{"class":260},[183,269,270],{"class":197},".",[183,272,273],{"class":253},"to_string",[183,275,276],{"class":201},"())",[183,278,279],{"class":197},"?",[183,281,282],{"class":201},";\n",[183,284,286,288,291,293,296,298,301,303,306,308,310,312,315,317,320],{"class":185,"line":285},4,[183,287,238],{"class":237},[183,289,290],{"class":241}," mutex ",[183,292,245],{"class":197},[183,294,295],{"class":193}," Mutex",[183,297,198],{"class":197},[183,299,300],{"class":253},"new",[183,302,257],{"class":201},[183,304,305],{"class":193},"LockOptions",[183,307,198],{"class":197},[183,309,300],{"class":253},[183,311,257],{"class":201},[183,313,314],{"class":241},"key",[183,316,208],{"class":201},[183,318,319],{"class":241}," conn",[183,321,322],{"class":201},"));\n",[158,324,325,328,329,270],{},[161,326,327],{},"Mutex::new"," returns ",[161,330,331],{},"Arc\u003CMutex>",[169,333,335],{"id":334},"acquiring","Acquiring",[174,337,339],{"className":176,"code":338,"language":178,"meta":179,"style":179},"\u002F\u002F Wait until the lock is free (bounded by max_wait if you set one).\nlet guard = mutex.lock().await?;\n\n\u002F\u002F One non-blocking attempt - errors with LockError::AcquireFail if held.\nlet guard = mutex.try_lock().await?;\n\n\u002F\u002F Wait up to a timeout, polling at retry_interval.\nuse std::time::Duration;\nlet guard = mutex\n    .try_lock_for(Duration::from_secs(5), Duration::from_millis(50))\n    .await?;\n",[161,340,341,347,377,381,386,412,417,423,443,455,498],{"__ignoreMap":179},[183,342,343],{"class":185,"line":186},[183,344,346],{"class":345},"sutJx","\u002F\u002F Wait until the lock is free (bounded by max_wait if you set one).\n",[183,348,349,351,354,356,359,361,364,367,369,373,375],{"class":185,"line":228},[183,350,238],{"class":237},[183,352,353],{"class":241}," guard ",[183,355,245],{"class":197},[183,357,358],{"class":241}," mutex",[183,360,270],{"class":197},[183,362,363],{"class":253},"lock",[183,365,366],{"class":201},"()",[183,368,270],{"class":197},[183,370,372],{"class":371},"sVHd0","await",[183,374,279],{"class":197},[183,376,282],{"class":201},[183,378,379],{"class":185,"line":234},[183,380,231],{"emptyLinePlaceholder":28},[183,382,383],{"class":185,"line":285},[183,384,385],{"class":345},"\u002F\u002F One non-blocking attempt - errors with LockError::AcquireFail if held.\n",[183,387,389,391,393,395,397,399,402,404,406,408,410],{"class":185,"line":388},5,[183,390,238],{"class":237},[183,392,353],{"class":241},[183,394,245],{"class":197},[183,396,358],{"class":241},[183,398,270],{"class":197},[183,400,401],{"class":253},"try_lock",[183,403,366],{"class":201},[183,405,270],{"class":197},[183,407,372],{"class":371},[183,409,279],{"class":197},[183,411,282],{"class":201},[183,413,415],{"class":185,"line":414},6,[183,416,231],{"emptyLinePlaceholder":28},[183,418,420],{"class":185,"line":419},7,[183,421,422],{"class":345},"\u002F\u002F Wait up to a timeout, polling at retry_interval.\n",[183,424,426,428,431,433,436,438,441],{"class":185,"line":425},8,[183,427,190],{"class":189},[183,429,430],{"class":193}," std",[183,432,198],{"class":197},[183,434,435],{"class":193},"time",[183,437,198],{"class":197},[183,439,440],{"class":193},"Duration",[183,442,282],{"class":201},[183,444,446,448,450,452],{"class":185,"line":445},9,[183,447,238],{"class":237},[183,449,353],{"class":241},[183,451,245],{"class":197},[183,453,454],{"class":241}," mutex\n",[183,456,458,461,464,466,468,470,473,475,479,482,485,487,490,492,495],{"class":185,"line":457},10,[183,459,460],{"class":197},"    .",[183,462,463],{"class":253},"try_lock_for",[183,465,257],{"class":201},[183,467,440],{"class":193},[183,469,198],{"class":197},[183,471,472],{"class":253},"from_secs",[183,474,257],{"class":201},[183,476,478],{"class":477},"srdBf","5",[183,480,481],{"class":201},"),",[183,483,484],{"class":193}," Duration",[183,486,198],{"class":197},[183,488,489],{"class":253},"from_millis",[183,491,257],{"class":201},[183,493,494],{"class":477},"50",[183,496,497],{"class":201},"))\n",[183,499,501,503,505,507],{"class":185,"line":500},11,[183,502,460],{"class":197},[183,504,372],{"class":371},[183,506,279],{"class":197},[183,508,282],{"class":201},[169,510,512],{"id":511},"holding-and-releasing","Holding and releasing",[158,514,515],{},"While you hold the guard, the lease renews in the background, so the critical section can take as long as it needs:",[174,517,519],{"className":176,"code":518,"language":178,"meta":179,"style":179},"let guard = mutex.lock().await?;\n\u002F\u002F ... critical section ...\nguard.release().await?; \u002F\u002F or just drop `guard`\n",[161,520,521,545,550],{"__ignoreMap":179},[183,522,523,525,527,529,531,533,535,537,539,541,543],{"class":185,"line":186},[183,524,238],{"class":237},[183,526,353],{"class":241},[183,528,245],{"class":197},[183,530,358],{"class":241},[183,532,270],{"class":197},[183,534,363],{"class":253},[183,536,366],{"class":201},[183,538,270],{"class":197},[183,540,372],{"class":371},[183,542,279],{"class":197},[183,544,282],{"class":201},[183,546,547],{"class":185,"line":228},[183,548,549],{"class":345},"\u002F\u002F ... critical section ...\n",[183,551,552,555,557,560,562,564,566,568,571],{"class":185,"line":234},[183,553,554],{"class":241},"guard",[183,556,270],{"class":197},[183,558,559],{"class":253},"release",[183,561,366],{"class":201},[183,563,270],{"class":197},[183,565,372],{"class":371},[183,567,279],{"class":197},[183,569,570],{"class":201},";",[183,572,573],{"class":345}," \u002F\u002F or just drop `guard`\n",[158,575,576,577,580,581,583,584,270],{},"Dropping the guard releases the lock too; ",[161,578,579],{},"release()"," is the explicit form that lets you ",[161,582,372],{}," the release and inspect the returned ",[585,586,587],"a",{"href":118},[161,588,589],{},"LockGuardState",[169,591,593],{"id":592},"checking-the-lease","Checking the lease",[158,595,596,599],{},[161,597,598],{},"get_state()"," reports the guard's current state without a Redis round-trip - useful before entering a section that must not run if the lease was lost:",[174,601,603],{"className":176,"code":602,"language":178,"meta":179,"style":179},"use distkit::lock::LockGuardState;\n\nlet guard = mutex.lock().await?;\nif guard.get_state().await == LockGuardState::Acquired {\n    \u002F\u002F safe to proceed\n}\n",[161,604,605,621,625,649,682,687],{"__ignoreMap":179},[183,606,607,609,611,613,615,617,619],{"class":185,"line":186},[183,608,190],{"class":189},[183,610,194],{"class":193},[183,612,198],{"class":197},[183,614,363],{"class":193},[183,616,198],{"class":197},[183,618,589],{"class":193},[183,620,282],{"class":201},[183,622,623],{"class":185,"line":228},[183,624,231],{"emptyLinePlaceholder":28},[183,626,627,629,631,633,635,637,639,641,643,645,647],{"class":185,"line":234},[183,628,238],{"class":237},[183,630,353],{"class":241},[183,632,245],{"class":197},[183,634,358],{"class":241},[183,636,270],{"class":197},[183,638,363],{"class":253},[183,640,366],{"class":201},[183,642,270],{"class":197},[183,644,372],{"class":371},[183,646,279],{"class":197},[183,648,282],{"class":201},[183,650,651,654,657,659,662,664,666,668,671,674,676,679],{"class":185,"line":285},[183,652,653],{"class":371},"if",[183,655,656],{"class":241}," guard",[183,658,270],{"class":197},[183,660,661],{"class":253},"get_state",[183,663,366],{"class":201},[183,665,270],{"class":197},[183,667,372],{"class":371},[183,669,670],{"class":197}," ==",[183,672,673],{"class":193}," LockGuardState",[183,675,198],{"class":197},[183,677,678],{"class":193},"Acquired",[183,680,681],{"class":201}," {\n",[183,683,684],{"class":185,"line":388},[183,685,686],{"class":345},"    \u002F\u002F safe to proceed\n",[183,688,689],{"class":185,"line":414},[183,690,691],{"class":201},"}\n",[693,694,695],"style",{},"html pre.shiki code .sw1J6, html code.shiki .sw1J6{--shiki-light:#F76D47;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":179,"searchDepth":186,"depth":228,"links":697},[698,699,700,701],{"id":171,"depth":228,"text":172},{"id":334,"depth":228,"text":335},{"id":511,"depth":228,"text":512},{"id":592,"depth":228,"text":593},"A distributed mutual-exclusion lock backed by Redis.","md",{},{"icon":105},{"title":102,"description":702},"w-6KD_05fqxlUzkOP-jS9M6fJI5mZLVQuoy4MPWDlvY",[709,711],{"title":62,"path":96,"stem":97,"description":710,"icon":100,"children":-1},"Redis-backed Mutex and RwLock that mirror tokio::sync, with RAII guards and background lease renewal.",{"title":107,"path":108,"stem":109,"description":712,"icon":110,"children":-1},"A writer-preferring distributed reader-writer lock.",1781569582594]